// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019-2021 NXP
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/of_device.h>
#include <linux/i2c.h>
#include <linux/v4l2-mediabus.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
#include <linux/regulator/consumer.h>
#include <media/v4l2-subdev.h>

#define MAX9271_MAX_SENSOR_NUM	4
#define CAMERA_USES_15HZ

#define ADDR_MAX9286		0x6A
#define ADDR_MAX9271		0x40
#define ADDR_MAX9271_ALL	(ADDR_MAX9271 + 5)  /* Broadcast address */

#define MIPI_CSI2_SENS_VC0_PAD_SOURCE	0
#define MIPI_CSI2_SENS_VC1_PAD_SOURCE	1
#define MIPI_CSI2_SENS_VC2_PAD_SOURCE	2
#define MIPI_CSI2_SENS_VC3_PAD_SOURCE	3
#define MIPI_CSI2_SENS_VCX_PADS_NUM		4

#define MAX_FPS		30
#define MIN_FPS		15
#define DEFAULT_FPS		30

#define ADDR_OV_SENSOR	0x30
#define ADDR_AP_SENSOR	0x5D

/*!
 * Maintains the information on the current state of the sesor.
 */
struct imxdpu_videomode {
	char name[64];		/* may not be needed */

	u32 pixelclock;	/* Hz */

	/* htotal (pixels) = hlen + hfp + hsync + hbp */
	u32 hlen;
	u32 hfp;
	u32 hbp;
	u32 hsync;

	/* field0 - vtotal (lines) = vlen + vfp + vsync + vbp */
	u32 vlen;
	u32 vfp;
	u32 vbp;
	u32 vsync;

	/* field1  */
	u32 vlen1;
	u32 vfp1;
	u32 vbp1;
	u32 vsync1;

	u32 flags;

	u32 format;
	u32 dest_format; /*buffer format for capture*/

	s16 clip_top;
	s16 clip_left;
	u16 clip_width;
	u16 clip_height;
};

enum ov10635_mode {
	ov10635_mode_MIN = 0,
	ov10635_mode_WXGA_1280_800 = 0,
	ov10635_mode_720P_1280_720 = 1,
	ov10635_mode_WVGA_752_480 = 2,
	ov10635_mode_VGA_640_480 = 3,
	ov10635_mode_CIF_352_288 = 4,
	ov10635_mode_QVGA_320_240 = 5,
	ov10635_mode_MAX = 5,
};

enum ov10635_frame_rate {
	OV10635_15_FPS = 0,
	OV10635_30_FPS,
};

struct sensor_data {
	struct v4l2_subdev	subdev;
	struct media_pad pads[MIPI_CSI2_SENS_VCX_PADS_NUM];
	struct i2c_client *i2c_client;
	struct v4l2_mbus_framefmt format;
	enum ov10635_frame_rate current_fr;
	enum ov10635_mode current_mode;
	struct v4l2_fract frame_interval;

	/* lock to protect shared members */
	struct mutex lock;
	char running;

	/* control settings */
	int brightness;
	int hue;
	int contrast;
	int saturation;
	int red;
	int green;
	int blue;
	int ae_mode;

	u32 mclk;
	u8 mclk_source;
	struct clk *sensor_clk;
	int v_channel;
	bool is_mipi;
	struct imxdpu_videomode cap_mode;

	unsigned int sensor_num;       /* sensor num connect max9271 */
	unsigned char sensor_is_there; /* Bit 0~3 for 4 cameras
					* 0b1= is there;
					* 0b0 = is not there
					*/
	struct gpio_desc *pwn_gpio;
};

#define OV10635_REG_PID		0x300A
#define OV10635_REG_VER		0x300B

struct reg_value {
	unsigned short reg_addr;
	unsigned char val;
	unsigned int delay_ms;
};

static int ov10635_framerates[] = {
	[OV10635_15_FPS] = 15,
	[OV10635_30_FPS] = 30,
};

static struct reg_value ov10635_init_data[] = {
	{ 0x0103, 0x01, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x300c, 0x61, 0 },
	{ 0x301b, 0xff, 0 },
	{ 0x301c, 0xff, 0 },
	{ 0x301a, 0xff, 0 },
	{ 0x3011, 0x42, 0 },
	{ 0x6900, 0x0c, 0 },
	{ 0x6901, 0x11, 0 },
	{ 0x3503, 0x10, 0 },
	{ 0x3025, 0x03, 0 },
	{ 0x3003, 0x20, 0 },
	{ 0x3004, 0x21, 0 },
	{ 0x3005, 0x20, 0 },
	{ 0x3006, 0x91, 0 },
	{ 0x3600, 0x74, 0 },
	{ 0x3601, 0x2b, 0 },
	{ 0x3612, 0x00, 0 },
	{ 0x3611, 0x67, 0 },
	{ 0x3633, 0xca, 0 },
	{ 0x3602, 0x2f, 0 },
	{ 0x3603, 0x00, 0 },
	{ 0x3630, 0x28, 0 },
	{ 0x3631, 0x16, 0 },
	{ 0x3714, 0x10, 0 },
	{ 0x371d, 0x01, 0 },
	{ 0x4300, 0x38, 0 },
	{ 0x3007, 0x01, 0 },
	{ 0x3024, 0x01, 0 },
	{ 0x3020, 0x0b, 0 },
	{ 0x3702, 0x20, 0 },
	{ 0x3703, 0x48, 0 },
	{ 0x3704, 0x32, 0 },
	{ 0x3709, 0xa8, 0 },
	{ 0x3709, 0xa8, 0 },
	{ 0x370c, 0xc7, 0 },
	{ 0x370d, 0x80, 0 },
	{ 0x3712, 0x00, 0 },
	{ 0x3713, 0x20, 0 },
	{ 0x3715, 0x04, 0 },
	{ 0x381d, 0x40, 0 },
	{ 0x381c, 0x00, 0 },
	{ 0x3822, 0x50, 0 },
	{ 0x3824, 0x50, 0 },
	{ 0x3815, 0x8c, 0 },
	{ 0x3804, 0x05, 0 },
	{ 0x3805, 0x1f, 0 },
	{ 0x3800, 0x00, 0 },
	{ 0x3801, 0x00, 0 },
	{ 0x3806, 0x03, 0 },
	{ 0x3807, 0x29, 0 },
	{ 0x3802, 0x00, 0 },
	{ 0x3803, 0x04, 0 },
	{ 0x3808, 0x05, 0 },
	{ 0x3809, 0x00, 0 },
	{ 0x380a, 0x03, 0 },
	{ 0x380b, 0x20, 0 },
	{ 0x380c, 0x07, 0 },
	{ 0x380d, 0x71, 0 },
	{ 0x6e42, 0x03, 0 },
	{ 0x6e43, 0x48, 0 },
	{ 0x380e, 0x03, 0 },
	{ 0x380f, 0x48, 0 },
	{ 0x3813, 0x02, 0 },
	{ 0x3811, 0x10, 0 },
	{ 0x381f, 0x0c, 0 },
	{ 0x3828, 0x03, 0 },
	{ 0x3829, 0x10, 0 },
	{ 0x382a, 0x10, 0 },
	{ 0x382b, 0x10, 0 },
	{ 0x3621, 0x64, 0 },
	{ 0x5005, 0x08, 0 },
	{ 0x56d5, 0x00, 0 },
	{ 0x56d6, 0x80, 0 },
	{ 0x56d7, 0x00, 0 },
	{ 0x56d8, 0x00, 0 },
	{ 0x56d9, 0x00, 0 },
	{ 0x56da, 0x80, 0 },
	{ 0x56db, 0x00, 0 },
	{ 0x56dc, 0x00, 0 },
	{ 0x56e8, 0x00, 0 },
	{ 0x56e9, 0x7f, 0 },
	{ 0x56ea, 0x00, 0 },
	{ 0x56eb, 0x7f, 0 },
	{ 0x5100, 0x00, 0 },
	{ 0x5101, 0x80, 0 },
	{ 0x5102, 0x00, 0 },
	{ 0x5103, 0x80, 0 },
	{ 0x5104, 0x00, 0 },
	{ 0x5105, 0x80, 0 },
	{ 0x5106, 0x00, 0 },
	{ 0x5107, 0x80, 0 },
	{ 0x5108, 0x00, 0 },
	{ 0x5109, 0x00, 0 },
	{ 0x510a, 0x00, 0 },
	{ 0x510b, 0x00, 0 },
	{ 0x510c, 0x00, 0 },
	{ 0x510d, 0x00, 0 },
	{ 0x510e, 0x00, 0 },
	{ 0x510f, 0x00, 0 },
	{ 0x5110, 0x00, 0 },
	{ 0x5111, 0x80, 0 },
	{ 0x5112, 0x00, 0 },
	{ 0x5113, 0x80, 0 },
	{ 0x5114, 0x00, 0 },
	{ 0x5115, 0x80, 0 },
	{ 0x5116, 0x00, 0 },
	{ 0x5117, 0x80, 0 },
	{ 0x5118, 0x00, 0 },
	{ 0x5119, 0x00, 0 },
	{ 0x511a, 0x00, 0 },
	{ 0x511b, 0x00, 0 },
	{ 0x511c, 0x00, 0 },
	{ 0x511d, 0x00, 0 },
	{ 0x511e, 0x00, 0 },
	{ 0x511f, 0x00, 0 },
	{ 0x56d0, 0x00, 0 },
	{ 0x5006, 0x24, 0 },
	{ 0x5608, 0x0d, 0 },
	{ 0x52d7, 0x06, 0 },
	{ 0x528d, 0x08, 0 },
	{ 0x5293, 0x12, 0 },
	{ 0x52d3, 0x12, 0 },
	{ 0x5288, 0x06, 0 },
	{ 0x5289, 0x20, 0 },
	{ 0x52c8, 0x06, 0 },
	{ 0x52c9, 0x20, 0 },
	{ 0x52cd, 0x04, 0 },
	{ 0x5381, 0x00, 0 },
	{ 0x5382, 0xff, 0 },
	{ 0x5589, 0x76, 0 },
	{ 0x558a, 0x47, 0 },
	{ 0x558b, 0xef, 0 },
	{ 0x558c, 0xc9, 0 },
	{ 0x558d, 0x49, 0 },
	{ 0x558e, 0x30, 0 },
	{ 0x558f, 0x67, 0 },
	{ 0x5590, 0x3f, 0 },
	{ 0x5591, 0xf0, 0 },
	{ 0x5592, 0x10, 0 },
	{ 0x55a2, 0x6d, 0 },
	{ 0x55a3, 0x55, 0 },
	{ 0x55a4, 0xc3, 0 },
	{ 0x55a5, 0xb5, 0 },
	{ 0x55a6, 0x43, 0 },
	{ 0x55a7, 0x38, 0 },
	{ 0x55a8, 0x5f, 0 },
	{ 0x55a9, 0x4b, 0 },
	{ 0x55aa, 0xf0, 0 },
	{ 0x55ab, 0x10, 0 },
	{ 0x5581, 0x52, 0 },
	{ 0x5300, 0x01, 0 },
	{ 0x5301, 0x00, 0 },
	{ 0x5302, 0x00, 0 },
	{ 0x5303, 0x0e, 0 },
	{ 0x5304, 0x00, 0 },
	{ 0x5305, 0x0e, 0 },
	{ 0x5306, 0x00, 0 },
	{ 0x5307, 0x36, 0 },
	{ 0x5308, 0x00, 0 },
	{ 0x5309, 0xd9, 0 },
	{ 0x530a, 0x00, 0 },
	{ 0x530b, 0x0f, 0 },
	{ 0x530c, 0x00, 0 },
	{ 0x530d, 0x2c, 0 },
	{ 0x530e, 0x00, 0 },
	{ 0x530f, 0x59, 0 },
	{ 0x5310, 0x00, 0 },
	{ 0x5311, 0x7b, 0 },
	{ 0x5312, 0x00, 0 },
	{ 0x5313, 0x22, 0 },
	{ 0x5314, 0x00, 0 },
	{ 0x5315, 0xd5, 0 },
	{ 0x5316, 0x00, 0 },
	{ 0x5317, 0x13, 0 },
	{ 0x5318, 0x00, 0 },
	{ 0x5319, 0x18, 0 },
	{ 0x531a, 0x00, 0 },
	{ 0x531b, 0x26, 0 },
	{ 0x531c, 0x00, 0 },
	{ 0x531d, 0xdc, 0 },
	{ 0x531e, 0x00, 0 },
	{ 0x531f, 0x02, 0 },
	{ 0x5320, 0x00, 0 },
	{ 0x5321, 0x24, 0 },
	{ 0x5322, 0x00, 0 },
	{ 0x5323, 0x56, 0 },
	{ 0x5324, 0x00, 0 },
	{ 0x5325, 0x85, 0 },
	{ 0x5326, 0x00, 0 },
	{ 0x5327, 0x20, 0 },
	{ 0x5609, 0x01, 0 },
	{ 0x560a, 0x40, 0 },
	{ 0x560b, 0x01, 0 },
	{ 0x560c, 0x40, 0 },
	{ 0x560d, 0x00, 0 },
	{ 0x560e, 0xfa, 0 },
	{ 0x560f, 0x00, 0 },
	{ 0x5610, 0xfa, 0 },
	{ 0x5611, 0x02, 0 },
	{ 0x5612, 0x80, 0 },
	{ 0x5613, 0x02, 0 },
	{ 0x5614, 0x80, 0 },
	{ 0x5615, 0x01, 0 },
	{ 0x5616, 0x2c, 0 },
	{ 0x5617, 0x01, 0 },
	{ 0x5618, 0x2c, 0 },
	{ 0x563b, 0x01, 0 },
	{ 0x563c, 0x01, 0 },
	{ 0x563d, 0x01, 0 },
	{ 0x563e, 0x01, 0 },
	{ 0x563f, 0x03, 0 },
	{ 0x5640, 0x03, 0 },
	{ 0x5641, 0x03, 0 },
	{ 0x5642, 0x05, 0 },
	{ 0x5643, 0x09, 0 },
	{ 0x5644, 0x05, 0 },
	{ 0x5645, 0x05, 0 },
	{ 0x5646, 0x05, 0 },
	{ 0x5647, 0x05, 0 },
	{ 0x5651, 0x00, 0 },
	{ 0x5652, 0x80, 0 },
	{ 0x521a, 0x01, 0 },
	{ 0x521b, 0x03, 0 },
	{ 0x521c, 0x06, 0 },
	{ 0x521d, 0x0a, 0 },
	{ 0x521e, 0x0e, 0 },
	{ 0x521f, 0x12, 0 },
	{ 0x5220, 0x16, 0 },
	{ 0x5223, 0x02, 0 },
	{ 0x5225, 0x04, 0 },
	{ 0x5227, 0x08, 0 },
	{ 0x5229, 0x0c, 0 },
	{ 0x522b, 0x12, 0 },
	{ 0x522d, 0x18, 0 },
	{ 0x522f, 0x1e, 0 },
	{ 0x5241, 0x04, 0 },
	{ 0x5242, 0x01, 0 },
	{ 0x5243, 0x03, 0 },
	{ 0x5244, 0x06, 0 },
	{ 0x5245, 0x0a, 0 },
	{ 0x5246, 0x0e, 0 },
	{ 0x5247, 0x12, 0 },
	{ 0x5248, 0x16, 0 },
	{ 0x524a, 0x03, 0 },
	{ 0x524c, 0x04, 0 },
	{ 0x524e, 0x08, 0 },
	{ 0x5250, 0x0c, 0 },
	{ 0x5252, 0x12, 0 },
	{ 0x5254, 0x18, 0 },
	{ 0x5256, 0x1e, 0 },
	{ 0x4606, 0x07, 0 },
	{ 0x4607, 0x71, 0 },
	{ 0x460a, 0x02, 0 },
	{ 0x460b, 0x70, 0 },
	{ 0x460c, 0x00, 0 },
	{ 0x4620, 0x0e, 0 },
	{ 0x4700, 0x04, 0 },
	{ 0x4701, 0x00, 0 },
	{ 0x4702, 0x01, 0 },
	{ 0x4004, 0x04, 0 },
	{ 0x4005, 0x18, 0 },
	{ 0x4001, 0x06, 0 },
	{ 0x4050, 0x22, 0 },
	{ 0x4051, 0x24, 0 },
	{ 0x4052, 0x02, 0 },
	{ 0x4057, 0x9c, 0 },
	{ 0x405a, 0x00, 0 },
	{ 0x4202, 0x02, 0 },
	{ 0x3023, 0x10, 0 },
	{ 0x0100, 0x0f, 0 },
	{ 0x0100, 0x0f, 0 },
	{ 0x6f10, 0x07, 0 },
	{ 0x6f11, 0x82, 0 },
	{ 0x6f12, 0x04, 0 },
	{ 0x6f13, 0x00, 0 },
	{ 0x6f14, 0x1f, 0 },
	{ 0x6f15, 0xdd, 0 },
	{ 0x6f16, 0x04, 0 },
	{ 0x6f17, 0x04, 0 },
	{ 0x6f18, 0x36, 0 },
	{ 0x6f19, 0x66, 0 },
	{ 0x6f1a, 0x04, 0 },
	{ 0x6f1b, 0x08, 0 },
	{ 0x6f1c, 0x0c, 0 },
	{ 0x6f1d, 0xe7, 0 },
	{ 0x6f1e, 0x04, 0 },
	{ 0x6f1f, 0x0c, 0 },
	{ 0xd000, 0x19, 0 },
	{ 0xd001, 0xa0, 0 },
	{ 0xd002, 0x00, 0 },
	{ 0xd003, 0x01, 0 },
	{ 0xd004, 0xa9, 0 },
	{ 0xd005, 0xad, 0 },
	{ 0xd006, 0x10, 0 },
	{ 0xd007, 0x40, 0 },
	{ 0xd008, 0x44, 0 },
	{ 0xd009, 0x00, 0 },
	{ 0xd00a, 0x68, 0 },
	{ 0xd00b, 0x00, 0 },
	{ 0xd00c, 0x15, 0 },
	{ 0xd00d, 0x00, 0 },
	{ 0xd00e, 0x00, 0 },
	{ 0xd00f, 0x00, 0 },
	{ 0xd010, 0x19, 0 },
	{ 0xd011, 0xa0, 0 },
	{ 0xd012, 0x00, 0 },
	{ 0xd013, 0x01, 0 },
	{ 0xd014, 0xa9, 0 },
	{ 0xd015, 0xad, 0 },
	{ 0xd016, 0x13, 0 },
	{ 0xd017, 0xd0, 0 },
	{ 0xd018, 0x44, 0 },
	{ 0xd019, 0x00, 0 },
	{ 0xd01a, 0x68, 0 },
	{ 0xd01b, 0x00, 0 },
	{ 0xd01c, 0x15, 0 },
	{ 0xd01d, 0x00, 0 },
	{ 0xd01e, 0x00, 0 },
	{ 0xd01f, 0x00, 0 },
	{ 0xd020, 0x19, 0 },
	{ 0xd021, 0xa0, 0 },
	{ 0xd022, 0x00, 0 },
	{ 0xd023, 0x01, 0 },
	{ 0xd024, 0xa9, 0 },
	{ 0xd025, 0xad, 0 },
	{ 0xd026, 0x14, 0 },
	{ 0xd027, 0xb8, 0 },
	{ 0xd028, 0x44, 0 },
	{ 0xd029, 0x00, 0 },
	{ 0xd02a, 0x68, 0 },
	{ 0xd02b, 0x00, 0 },
	{ 0xd02c, 0x15, 0 },
	{ 0xd02d, 0x00, 0 },
	{ 0xd02e, 0x00, 0 },
	{ 0xd02f, 0x00, 0 },
	{ 0xd030, 0x19, 0 },
	{ 0xd031, 0xa0, 0 },
	{ 0xd032, 0x00, 0 },
	{ 0xd033, 0x01, 0 },
	{ 0xd034, 0xa9, 0 },
	{ 0xd035, 0xad, 0 },
	{ 0xd036, 0x14, 0 },
	{ 0xd037, 0xdc, 0 },
	{ 0xd038, 0x44, 0 },
	{ 0xd039, 0x00, 0 },
	{ 0xd03a, 0x68, 0 },
	{ 0xd03b, 0x00, 0 },
	{ 0xd03c, 0x15, 0 },
	{ 0xd03d, 0x00, 0 },
	{ 0xd03e, 0x00, 0 },
	{ 0xd03f, 0x00, 0 },
	{ 0xd040, 0x9c, 0 },
	{ 0xd041, 0x21, 0 },
	{ 0xd042, 0xff, 0 },
	{ 0xd043, 0xe4, 0 },
	{ 0xd044, 0xd4, 0 },
	{ 0xd045, 0x01, 0 },
	{ 0xd046, 0x48, 0 },
	{ 0xd047, 0x00, 0 },
	{ 0xd048, 0xd4, 0 },
	{ 0xd049, 0x01, 0 },
	{ 0xd04a, 0x50, 0 },
	{ 0xd04b, 0x04, 0 },
	{ 0xd04c, 0xd4, 0 },
	{ 0xd04d, 0x01, 0 },
	{ 0xd04e, 0x60, 0 },
	{ 0xd04f, 0x08, 0 },
	{ 0xd050, 0xd4, 0 },
	{ 0xd051, 0x01, 0 },
	{ 0xd052, 0x70, 0 },
	{ 0xd053, 0x0c, 0 },
	{ 0xd054, 0xd4, 0 },
	{ 0xd055, 0x01, 0 },
	{ 0xd056, 0x80, 0 },
	{ 0xd057, 0x10, 0 },
	{ 0xd058, 0x19, 0 },
	{ 0xd059, 0xc0, 0 },
	{ 0xd05a, 0x00, 0 },
	{ 0xd05b, 0x01, 0 },
	{ 0xd05c, 0xa9, 0 },
	{ 0xd05d, 0xce, 0 },
	{ 0xd05e, 0x02, 0 },
	{ 0xd05f, 0xa4, 0 },
	{ 0xd060, 0x9c, 0 },
	{ 0xd061, 0xa0, 0 },
	{ 0xd062, 0x00, 0 },
	{ 0xd063, 0x00, 0 },
	{ 0xd064, 0x84, 0 },
	{ 0xd065, 0x6e, 0 },
	{ 0xd066, 0x00, 0 },
	{ 0xd067, 0x00, 0 },
	{ 0xd068, 0xd8, 0 },
	{ 0xd069, 0x03, 0 },
	{ 0xd06a, 0x28, 0 },
	{ 0xd06b, 0x76, 0 },
	{ 0xd06c, 0x1a, 0 },
	{ 0xd06d, 0x00, 0 },
	{ 0xd06e, 0x00, 0 },
	{ 0xd06f, 0x01, 0 },
	{ 0xd070, 0xaa, 0 },
	{ 0xd071, 0x10, 0 },
	{ 0xd072, 0x03, 0 },
	{ 0xd073, 0xf0, 0 },
	{ 0xd074, 0x18, 0 },
	{ 0xd075, 0x60, 0 },
	{ 0xd076, 0x00, 0 },
	{ 0xd077, 0x01, 0 },
	{ 0xd078, 0xa8, 0 },
	{ 0xd079, 0x63, 0 },
	{ 0xd07a, 0x07, 0 },
	{ 0xd07b, 0x80, 0 },
	{ 0xd07c, 0xe0, 0 },
	{ 0xd07d, 0xa0, 0 },
	{ 0xd07e, 0x00, 0 },
	{ 0xd07f, 0x04, 0 },
	{ 0xd080, 0x18, 0 },
	{ 0xd081, 0xc0, 0 },
	{ 0xd082, 0x00, 0 },
	{ 0xd083, 0x00, 0 },
	{ 0xd084, 0xa8, 0 },
	{ 0xd085, 0xc6, 0 },
	{ 0xd086, 0x00, 0 },
	{ 0xd087, 0x00, 0 },
	{ 0xd088, 0x8c, 0 },
	{ 0xd089, 0x63, 0 },
	{ 0xd08a, 0x00, 0 },
	{ 0xd08b, 0x00, 0 },
	{ 0xd08c, 0xd4, 0 },
	{ 0xd08d, 0x01, 0 },
	{ 0xd08e, 0x28, 0 },
	{ 0xd08f, 0x14, 0 },
	{ 0xd090, 0xd4, 0 },
	{ 0xd091, 0x01, 0 },
	{ 0xd092, 0x30, 0 },
	{ 0xd093, 0x18, 0 },
	{ 0xd094, 0x07, 0 },
	{ 0xd095, 0xff, 0 },
	{ 0xd096, 0xf8, 0 },
	{ 0xd097, 0xfd, 0 },
	{ 0xd098, 0x9c, 0 },
	{ 0xd099, 0x80, 0 },
	{ 0xd09a, 0x00, 0 },
	{ 0xd09b, 0x03, 0 },
	{ 0xd09c, 0xa5, 0 },
	{ 0xd09d, 0x6b, 0 },
	{ 0xd09e, 0x00, 0 },
	{ 0xd09f, 0xff, 0 },
	{ 0xd0a0, 0x18, 0 },
	{ 0xd0a1, 0xc0, 0 },
	{ 0xd0a2, 0x00, 0 },
	{ 0xd0a3, 0x01, 0 },
	{ 0xd0a4, 0xa8, 0 },
	{ 0xd0a5, 0xc6, 0 },
	{ 0xd0a6, 0x01, 0 },
	{ 0xd0a7, 0x02, 0 },
	{ 0xd0a8, 0xe1, 0 },
	{ 0xd0a9, 0x6b, 0 },
	{ 0xd0aa, 0x58, 0 },
	{ 0xd0ab, 0x00, 0 },
	{ 0xd0ac, 0x84, 0 },
	{ 0xd0ad, 0x8e, 0 },
	{ 0xd0ae, 0x00, 0 },
	{ 0xd0af, 0x00, 0 },
	{ 0xd0b0, 0xe1, 0 },
	{ 0xd0b1, 0x6b, 0 },
	{ 0xd0b2, 0x30, 0 },
	{ 0xd0b3, 0x00, 0 },
	{ 0xd0b4, 0x98, 0 },
	{ 0xd0b5, 0xb0, 0 },
	{ 0xd0b6, 0x00, 0 },
	{ 0xd0b7, 0x00, 0 },
	{ 0xd0b8, 0x8c, 0 },
	{ 0xd0b9, 0x64, 0 },
	{ 0xd0ba, 0x00, 0 },
	{ 0xd0bb, 0x6e, 0 },
	{ 0xd0bc, 0xe5, 0 },
	{ 0xd0bd, 0xa5, 0 },
	{ 0xd0be, 0x18, 0 },
	{ 0xd0bf, 0x00, 0 },
	{ 0xd0c0, 0x10, 0 },
	{ 0xd0c1, 0x00, 0 },
	{ 0xd0c2, 0x00, 0 },
	{ 0xd0c3, 0x06, 0 },
	{ 0xd0c4, 0x95, 0 },
	{ 0xd0c5, 0x8b, 0 },
	{ 0xd0c6, 0x00, 0 },
	{ 0xd0c7, 0x00, 0 },
	{ 0xd0c8, 0x94, 0 },
	{ 0xd0c9, 0xa4, 0 },
	{ 0xd0ca, 0x00, 0 },
	{ 0xd0cb, 0x70, 0 },
	{ 0xd0cc, 0xe5, 0 },
	{ 0xd0cd, 0x65, 0 },
	{ 0xd0ce, 0x60, 0 },
	{ 0xd0cf, 0x00, 0 },
	{ 0xd0d0, 0x0c, 0 },
	{ 0xd0d1, 0x00, 0 },
	{ 0xd0d2, 0x00, 0 },
	{ 0xd0d3, 0x62, 0 },
	{ 0xd0d4, 0x15, 0 },
	{ 0xd0d5, 0x00, 0 },
	{ 0xd0d6, 0x00, 0 },
	{ 0xd0d7, 0x00, 0 },
	{ 0xd0d8, 0x18, 0 },
	{ 0xd0d9, 0x60, 0 },
	{ 0xd0da, 0x80, 0 },
	{ 0xd0db, 0x06, 0 },
	{ 0xd0dc, 0xa8, 0 },
	{ 0xd0dd, 0x83, 0 },
	{ 0xd0de, 0x38, 0 },
	{ 0xd0df, 0x29, 0 },
	{ 0xd0e0, 0xa8, 0 },
	{ 0xd0e1, 0xe3, 0 },
	{ 0xd0e2, 0x40, 0 },
	{ 0xd0e3, 0x08, 0 },
	{ 0xd0e4, 0x8c, 0 },
	{ 0xd0e5, 0x84, 0 },
	{ 0xd0e6, 0x00, 0 },
	{ 0xd0e7, 0x00, 0 },
	{ 0xd0e8, 0xa8, 0 },
	{ 0xd0e9, 0xa3, 0 },
	{ 0xd0ea, 0x40, 0 },
	{ 0xd0eb, 0x09, 0 },
	{ 0xd0ec, 0xa8, 0 },
	{ 0xd0ed, 0xc3, 0 },
	{ 0xd0ee, 0x38, 0 },
	{ 0xd0ef, 0x2a, 0 },
	{ 0xd0f0, 0xd8, 0 },
	{ 0xd0f1, 0x07, 0 },
	{ 0xd0f2, 0x20, 0 },
	{ 0xd0f3, 0x00, 0 },
	{ 0xd0f4, 0x8c, 0 },
	{ 0xd0f5, 0x66, 0 },
	{ 0xd0f6, 0x00, 0 },
	{ 0xd0f7, 0x00, 0 },
	{ 0xd0f8, 0xd8, 0 },
	{ 0xd0f9, 0x05, 0 },
	{ 0xd0fa, 0x18, 0 },
	{ 0xd0fb, 0x00, 0 },
	{ 0xd0fc, 0x18, 0 },
	{ 0xd0fd, 0x60, 0 },
	{ 0xd0fe, 0x00, 0 },
	{ 0xd0ff, 0x01, 0 },
	{ 0xd100, 0x98, 0 },
	{ 0xd101, 0x90, 0 },
	{ 0xd102, 0x00, 0 },
	{ 0xd103, 0x00, 0 },
	{ 0xd104, 0x84, 0 },
	{ 0xd105, 0xae, 0 },
	{ 0xd106, 0x00, 0 },
	{ 0xd107, 0x00, 0 },
	{ 0xd108, 0xa8, 0 },
	{ 0xd109, 0x63, 0 },
	{ 0xd10a, 0x06, 0 },
	{ 0xd10b, 0x4c, 0 },
	{ 0xd10c, 0x9c, 0 },
	{ 0xd10d, 0xc0, 0 },
	{ 0xd10e, 0x00, 0 },
	{ 0xd10f, 0x00, 0 },
	{ 0xd110, 0xd8, 0 },
	{ 0xd111, 0x03, 0 },
	{ 0xd112, 0x30, 0 },
	{ 0xd113, 0x00, 0 },
	{ 0xd114, 0x8c, 0 },
	{ 0xd115, 0x65, 0 },
	{ 0xd116, 0x00, 0 },
	{ 0xd117, 0x6e, 0 },
	{ 0xd118, 0xe5, 0 },
	{ 0xd119, 0x84, 0 },
	{ 0xd11a, 0x18, 0 },
	{ 0xd11b, 0x00, 0 },
	{ 0xd11c, 0x10, 0 },
	{ 0xd11d, 0x00, 0 },
	{ 0xd11e, 0x00, 0 },
	{ 0xd11f, 0x07, 0 },
	{ 0xd120, 0x18, 0 },
	{ 0xd121, 0x80, 0 },
	{ 0xd122, 0x80, 0 },
	{ 0xd123, 0x06, 0 },
	{ 0xd124, 0x94, 0 },
	{ 0xd125, 0x65, 0 },
	{ 0xd126, 0x00, 0 },
	{ 0xd127, 0x70, 0 },
	{ 0xd128, 0xe5, 0 },
	{ 0xd129, 0x43, 0 },
	{ 0xd12a, 0x60, 0 },
	{ 0xd12b, 0x00, 0 },
	{ 0xd12c, 0x0c, 0 },
	{ 0xd12d, 0x00, 0 },
	{ 0xd12e, 0x00, 0 },
	{ 0xd12f, 0x3e, 0 },
	{ 0xd130, 0xa8, 0 },
	{ 0xd131, 0x64, 0 },
	{ 0xd132, 0x38, 0 },
	{ 0xd133, 0x24, 0 },
	{ 0xd134, 0x18, 0 },
	{ 0xd135, 0x80, 0 },
	{ 0xd136, 0x80, 0 },
	{ 0xd137, 0x06, 0 },
	{ 0xd138, 0xa8, 0 },
	{ 0xd139, 0x64, 0 },
	{ 0xd13a, 0x38, 0 },
	{ 0xd13b, 0x24, 0 },
	{ 0xd13c, 0x8c, 0 },
	{ 0xd13d, 0x63, 0 },
	{ 0xd13e, 0x00, 0 },
	{ 0xd13f, 0x00, 0 },
	{ 0xd140, 0xa4, 0 },
	{ 0xd141, 0x63, 0 },
	{ 0xd142, 0x00, 0 },
	{ 0xd143, 0x40, 0 },
	{ 0xd144, 0xbc, 0 },
	{ 0xd145, 0x23, 0 },
	{ 0xd146, 0x00, 0 },
	{ 0xd147, 0x00, 0 },
	{ 0xd148, 0x0c, 0 },
	{ 0xd149, 0x00, 0 },
	{ 0xd14a, 0x00, 0 },
	{ 0xd14b, 0x2a, 0 },
	{ 0xd14c, 0xa8, 0 },
	{ 0xd14d, 0x64, 0 },
	{ 0xd14e, 0x6e, 0 },
	{ 0xd14f, 0x44, 0 },
	{ 0xd150, 0x19, 0 },
	{ 0xd151, 0x00, 0 },
	{ 0xd152, 0x80, 0 },
	{ 0xd153, 0x06, 0 },
	{ 0xd154, 0xa8, 0 },
	{ 0xd155, 0xe8, 0 },
	{ 0xd156, 0x3d, 0 },
	{ 0xd157, 0x05, 0 },
	{ 0xd158, 0x8c, 0 },
	{ 0xd159, 0x67, 0 },
	{ 0xd15a, 0x00, 0 },
	{ 0xd15b, 0x00, 0 },
	{ 0xd15c, 0xb8, 0 },
	{ 0xd15d, 0x63, 0 },
	{ 0xd15e, 0x00, 0 },
	{ 0xd15f, 0x18, 0 },
	{ 0xd160, 0xb8, 0 },
	{ 0xd161, 0x63, 0 },
	{ 0xd162, 0x00, 0 },
	{ 0xd163, 0x98, 0 },
	{ 0xd164, 0xbc, 0 },
	{ 0xd165, 0x03, 0 },
	{ 0xd166, 0x00, 0 },
	{ 0xd167, 0x00, 0 },
	{ 0xd168, 0x10, 0 },
	{ 0xd169, 0x00, 0 },
	{ 0xd16a, 0x00, 0 },
	{ 0xd16b, 0x10, 0 },
	{ 0xd16c, 0xa9, 0 },
	{ 0xd16d, 0x48, 0 },
	{ 0xd16e, 0x67, 0 },
	{ 0xd16f, 0x02, 0 },
	{ 0xd170, 0xb8, 0 },
	{ 0xd171, 0xa3, 0 },
	{ 0xd172, 0x00, 0 },
	{ 0xd173, 0x19, 0 },
	{ 0xd174, 0x8c, 0 },
	{ 0xd175, 0x8a, 0 },
	{ 0xd176, 0x00, 0 },
	{ 0xd177, 0x00, 0 },
	{ 0xd178, 0xa9, 0 },
	{ 0xd179, 0x68, 0 },
	{ 0xd17a, 0x67, 0 },
	{ 0xd17b, 0x03, 0 },
	{ 0xd17c, 0xb8, 0 },
	{ 0xd17d, 0xc4, 0 },
	{ 0xd17e, 0x00, 0 },
	{ 0xd17f, 0x08, 0 },
	{ 0xd180, 0x8c, 0 },
	{ 0xd181, 0x6b, 0 },
	{ 0xd182, 0x00, 0 },
	{ 0xd183, 0x00, 0 },
	{ 0xd184, 0xb8, 0 },
	{ 0xd185, 0x85, 0 },
	{ 0xd186, 0x00, 0 },
	{ 0xd187, 0x98, 0 },
	{ 0xd188, 0xe0, 0 },
	{ 0xd189, 0x63, 0 },
	{ 0xd18a, 0x30, 0 },
	{ 0xd18b, 0x04, 0 },
	{ 0xd18c, 0xe0, 0 },
	{ 0xd18d, 0x64, 0 },
	{ 0xd18e, 0x18, 0 },
	{ 0xd18f, 0x00, 0 },
	{ 0xd190, 0xa4, 0 },
	{ 0xd191, 0x83, 0 },
	{ 0xd192, 0xff, 0 },
	{ 0xd193, 0xff, 0 },
	{ 0xd194, 0xb8, 0 },
	{ 0xd195, 0x64, 0 },
	{ 0xd196, 0x00, 0 },
	{ 0xd197, 0x48, 0 },
	{ 0xd198, 0xd8, 0 },
	{ 0xd199, 0x0a, 0 },
	{ 0xd19a, 0x18, 0 },
	{ 0xd19b, 0x00, 0 },
	{ 0xd19c, 0xd8, 0 },
	{ 0xd19d, 0x0b, 0 },
	{ 0xd19e, 0x20, 0 },
	{ 0xd19f, 0x00, 0 },
	{ 0xd1a0, 0x9c, 0 },
	{ 0xd1a1, 0x60, 0 },
	{ 0xd1a2, 0x00, 0 },
	{ 0xd1a3, 0x00, 0 },
	{ 0xd1a4, 0xd8, 0 },
	{ 0xd1a5, 0x07, 0 },
	{ 0xd1a6, 0x18, 0 },
	{ 0xd1a7, 0x00, 0 },
	{ 0xd1a8, 0xa8, 0 },
	{ 0xd1a9, 0x68, 0 },
	{ 0xd1aa, 0x38, 0 },
	{ 0xd1ab, 0x22, 0 },
	{ 0xd1ac, 0x9c, 0 },
	{ 0xd1ad, 0x80, 0 },
	{ 0xd1ae, 0x00, 0 },
	{ 0xd1af, 0x70, 0 },
	{ 0xd1b0, 0xa8, 0 },
	{ 0xd1b1, 0xe8, 0 },
	{ 0xd1b2, 0x38, 0 },
	{ 0xd1b3, 0x43, 0 },
	{ 0xd1b4, 0xd8, 0 },
	{ 0xd1b5, 0x03, 0 },
	{ 0xd1b6, 0x20, 0 },
	{ 0xd1b7, 0x00, 0 },
	{ 0xd1b8, 0x9c, 0 },
	{ 0xd1b9, 0xa0, 0 },
	{ 0xd1ba, 0x00, 0 },
	{ 0xd1bb, 0x00, 0 },
	{ 0xd1bc, 0xa8, 0 },
	{ 0xd1bd, 0xc8, 0 },
	{ 0xd1be, 0x38, 0 },
	{ 0xd1bf, 0x42, 0 },
	{ 0xd1c0, 0x8c, 0 },
	{ 0xd1c1, 0x66, 0 },
	{ 0xd1c2, 0x00, 0 },
	{ 0xd1c3, 0x00, 0 },
	{ 0xd1c4, 0x9c, 0 },
	{ 0xd1c5, 0xa5, 0 },
	{ 0xd1c6, 0x00, 0 },
	{ 0xd1c7, 0x01, 0 },
	{ 0xd1c8, 0xb8, 0 },
	{ 0xd1c9, 0x83, 0 },
	{ 0xd1ca, 0x00, 0 },
	{ 0xd1cb, 0x08, 0 },
	{ 0xd1cc, 0xa4, 0 },
	{ 0xd1cd, 0xa5, 0 },
	{ 0xd1ce, 0x00, 0 },
	{ 0xd1cf, 0xff, 0 },
	{ 0xd1d0, 0x8c, 0 },
	{ 0xd1d1, 0x67, 0 },
	{ 0xd1d2, 0x00, 0 },
	{ 0xd1d3, 0x00, 0 },
	{ 0xd1d4, 0xe0, 0 },
	{ 0xd1d5, 0x63, 0 },
	{ 0xd1d6, 0x20, 0 },
	{ 0xd1d7, 0x00, 0 },
	{ 0xd1d8, 0xa4, 0 },
	{ 0xd1d9, 0x63, 0 },
	{ 0xd1da, 0xff, 0 },
	{ 0xd1db, 0xff, 0 },
	{ 0xd1dc, 0xbc, 0 },
	{ 0xd1dd, 0x43, 0 },
	{ 0xd1de, 0x00, 0 },
	{ 0xd1df, 0x07, 0 },
	{ 0xd1e0, 0x0c, 0 },
	{ 0xd1e1, 0x00, 0 },
	{ 0xd1e2, 0x00, 0 },
	{ 0xd1e3, 0x5b, 0 },
	{ 0xd1e4, 0xbc, 0 },
	{ 0xd1e5, 0x05, 0 },
	{ 0xd1e6, 0x00, 0 },
	{ 0xd1e7, 0x02, 0 },
	{ 0xd1e8, 0x03, 0 },
	{ 0xd1e9, 0xff, 0 },
	{ 0xd1ea, 0xff, 0 },
	{ 0xd1eb, 0xf6, 0 },
	{ 0xd1ec, 0x9c, 0 },
	{ 0xd1ed, 0xa0, 0 },
	{ 0xd1ee, 0x00, 0 },
	{ 0xd1ef, 0x00, 0 },
	{ 0xd1f0, 0xa8, 0 },
	{ 0xd1f1, 0xa4, 0 },
	{ 0xd1f2, 0x55, 0 },
	{ 0xd1f3, 0x86, 0 },
	{ 0xd1f4, 0x8c, 0 },
	{ 0xd1f5, 0x63, 0 },
	{ 0xd1f6, 0x00, 0 },
	{ 0xd1f7, 0x00, 0 },
	{ 0xd1f8, 0xa8, 0 },
	{ 0xd1f9, 0xc4, 0 },
	{ 0xd1fa, 0x6e, 0 },
	{ 0xd1fb, 0x45, 0 },
	{ 0xd1fc, 0xa8, 0 },
	{ 0xd1fd, 0xe4, 0 },
	{ 0xd1fe, 0x55, 0 },
	{ 0xd1ff, 0x87, 0 },
	{ 0xd200, 0xd8, 0 },
	{ 0xd201, 0x05, 0 },
	{ 0xd202, 0x18, 0 },
	{ 0xd203, 0x00, 0 },
	{ 0xd204, 0x8c, 0 },
	{ 0xd205, 0x66, 0 },
	{ 0xd206, 0x00, 0 },
	{ 0xd207, 0x00, 0 },
	{ 0xd208, 0xa8, 0 },
	{ 0xd209, 0xa4, 0 },
	{ 0xd20a, 0x6e, 0 },
	{ 0xd20b, 0x46, 0 },
	{ 0xd20c, 0xd8, 0 },
	{ 0xd20d, 0x07, 0 },
	{ 0xd20e, 0x18, 0 },
	{ 0xd20f, 0x00, 0 },
	{ 0xd210, 0xa8, 0 },
	{ 0xd211, 0x84, 0 },
	{ 0xd212, 0x55, 0 },
	{ 0xd213, 0x88, 0 },
	{ 0xd214, 0x8c, 0 },
	{ 0xd215, 0x65, 0 },
	{ 0xd216, 0x00, 0 },
	{ 0xd217, 0x00, 0 },
	{ 0xd218, 0xd8, 0 },
	{ 0xd219, 0x04, 0 },
	{ 0xd21a, 0x18, 0 },
	{ 0xd21b, 0x00, 0 },
	{ 0xd21c, 0x03, 0 },
	{ 0xd21d, 0xff, 0 },
	{ 0xd21e, 0xff, 0 },
	{ 0xd21f, 0xce, 0 },
	{ 0xd220, 0x19, 0 },
	{ 0xd221, 0x00, 0 },
	{ 0xd222, 0x80, 0 },
	{ 0xd223, 0x06, 0 },
	{ 0xd224, 0x8c, 0 },
	{ 0xd225, 0x63, 0 },
	{ 0xd226, 0x00, 0 },
	{ 0xd227, 0x00, 0 },
	{ 0xd228, 0xa4, 0 },
	{ 0xd229, 0x63, 0 },
	{ 0xd22a, 0x00, 0 },
	{ 0xd22b, 0x40, 0 },
	{ 0xd22c, 0xbc, 0 },
	{ 0xd22d, 0x23, 0 },
	{ 0xd22e, 0x00, 0 },
	{ 0xd22f, 0x00, 0 },
	{ 0xd230, 0x13, 0 },
	{ 0xd231, 0xff, 0 },
	{ 0xd232, 0xff, 0 },
	{ 0xd233, 0xc8, 0 },
	{ 0xd234, 0x9d, 0 },
	{ 0xd235, 0x00, 0 },
	{ 0xd236, 0x00, 0 },
	{ 0xd237, 0x40, 0 },
	{ 0xd238, 0xa8, 0 },
	{ 0xd239, 0x64, 0 },
	{ 0xd23a, 0x55, 0 },
	{ 0xd23b, 0x86, 0 },
	{ 0xd23c, 0xa8, 0 },
	{ 0xd23d, 0xa4, 0 },
	{ 0xd23e, 0x55, 0 },
	{ 0xd23f, 0x87, 0 },
	{ 0xd240, 0xd8, 0 },
	{ 0xd241, 0x03, 0 },
	{ 0xd242, 0x40, 0 },
	{ 0xd243, 0x00, 0 },
	{ 0xd244, 0xa8, 0 },
	{ 0xd245, 0x64, 0 },
	{ 0xd246, 0x55, 0 },
	{ 0xd247, 0x88, 0 },
	{ 0xd248, 0xd8, 0 },
	{ 0xd249, 0x05, 0 },
	{ 0xd24a, 0x40, 0 },
	{ 0xd24b, 0x00, 0 },
	{ 0xd24c, 0xd8, 0 },
	{ 0xd24d, 0x03, 0 },
	{ 0xd24e, 0x40, 0 },
	{ 0xd24f, 0x00, 0 },
	{ 0xd250, 0x03, 0 },
	{ 0xd251, 0xff, 0 },
	{ 0xd252, 0xff, 0 },
	{ 0xd253, 0xc1, 0 },
	{ 0xd254, 0x19, 0 },
	{ 0xd255, 0x00, 0 },
	{ 0xd256, 0x80, 0 },
	{ 0xd257, 0x06, 0 },
	{ 0xd258, 0x94, 0 },
	{ 0xd259, 0x84, 0 },
	{ 0xd25a, 0x00, 0 },
	{ 0xd25b, 0x72, 0 },
	{ 0xd25c, 0xe5, 0 },
	{ 0xd25d, 0xa4, 0 },
	{ 0xd25e, 0x60, 0 },
	{ 0xd25f, 0x00, 0 },
	{ 0xd260, 0x0c, 0 },
	{ 0xd261, 0x00, 0 },
	{ 0xd262, 0x00, 0 },
	{ 0xd263, 0x3f, 0 },
	{ 0xd264, 0x9d, 0 },
	{ 0xd265, 0x60, 0 },
	{ 0xd266, 0x01, 0 },
	{ 0xd267, 0x00, 0 },
	{ 0xd268, 0x85, 0 },
	{ 0xd269, 0x4e, 0 },
	{ 0xd26a, 0x00, 0 },
	{ 0xd26b, 0x00, 0 },
	{ 0xd26c, 0x98, 0 },
	{ 0xd26d, 0x70, 0 },
	{ 0xd26e, 0x00, 0 },
	{ 0xd26f, 0x00, 0 },
	{ 0xd270, 0x8c, 0 },
	{ 0xd271, 0x8a, 0 },
	{ 0xd272, 0x00, 0 },
	{ 0xd273, 0x6f, 0 },
	{ 0xd274, 0xe5, 0 },
	{ 0xd275, 0x63, 0 },
	{ 0xd276, 0x20, 0 },
	{ 0xd277, 0x00, 0 },
	{ 0xd278, 0x10, 0 },
	{ 0xd279, 0x00, 0 },
	{ 0xd27a, 0x00, 0 },
	{ 0xd27b, 0x07, 0 },
	{ 0xd27c, 0x15, 0 },
	{ 0xd27d, 0x00, 0 },
	{ 0xd27e, 0x00, 0 },
	{ 0xd27f, 0x00, 0 },
	{ 0xd280, 0x8c, 0 },
	{ 0xd281, 0xaa, 0 },
	{ 0xd282, 0x00, 0 },
	{ 0xd283, 0x6e, 0 },
	{ 0xd284, 0xe0, 0 },
	{ 0xd285, 0x63, 0 },
	{ 0xd286, 0x28, 0 },
	{ 0xd287, 0x02, 0 },
	{ 0xd288, 0xe0, 0 },
	{ 0xd289, 0x84, 0 },
	{ 0xd28a, 0x28, 0 },
	{ 0xd28b, 0x02, 0 },
	{ 0xd28c, 0x07, 0 },
	{ 0xd28d, 0xff, 0 },
	{ 0xd28e, 0xf8, 0 },
	{ 0xd28f, 0x66, 0 },
	{ 0xd290, 0xe0, 0 },
	{ 0xd291, 0x63, 0 },
	{ 0xd292, 0x5b, 0 },
	{ 0xd293, 0x06, 0 },
	{ 0xd294, 0x8c, 0 },
	{ 0xd295, 0x6a, 0 },
	{ 0xd296, 0x00, 0 },
	{ 0xd297, 0x77, 0 },
	{ 0xd298, 0xe0, 0 },
	{ 0xd299, 0x63, 0 },
	{ 0xd29a, 0x5b, 0 },
	{ 0xd29b, 0x06, 0 },
	{ 0xd29c, 0xbd, 0 },
	{ 0xd29d, 0x63, 0 },
	{ 0xd29e, 0x00, 0 },
	{ 0xd29f, 0x00, 0 },
	{ 0xd2a0, 0x0c, 0 },
	{ 0xd2a1, 0x00, 0 },
	{ 0xd2a2, 0x00, 0 },
	{ 0xd2a3, 0x3c, 0 },
	{ 0xd2a4, 0x15, 0 },
	{ 0xd2a5, 0x00, 0 },
	{ 0xd2a6, 0x00, 0 },
	{ 0xd2a7, 0x00, 0 },
	{ 0xd2a8, 0x8c, 0 },
	{ 0xd2a9, 0x8a, 0 },
	{ 0xd2aa, 0x00, 0 },
	{ 0xd2ab, 0x78, 0 },
	{ 0xd2ac, 0xb8, 0 },
	{ 0xd2ad, 0x63, 0 },
	{ 0xd2ae, 0x00, 0 },
	{ 0xd2af, 0x88, 0 },
	{ 0xd2b0, 0xe1, 0 },
	{ 0xd2b1, 0x64, 0 },
	{ 0xd2b2, 0x5b, 0 },
	{ 0xd2b3, 0x06, 0 },
	{ 0xd2b4, 0xbd, 0 },
	{ 0xd2b5, 0x6b, 0 },
	{ 0xd2b6, 0x00, 0 },
	{ 0xd2b7, 0x00, 0 },
	{ 0xd2b8, 0x0c, 0 },
	{ 0xd2b9, 0x00, 0 },
	{ 0xd2ba, 0x00, 0 },
	{ 0xd2bb, 0x34, 0 },
	{ 0xd2bc, 0xd4, 0 },
	{ 0xd2bd, 0x01, 0 },
	{ 0xd2be, 0x18, 0 },
	{ 0xd2bf, 0x14, 0 },
	{ 0xd2c0, 0xb9, 0 },
	{ 0xd2c1, 0x6b, 0 },
	{ 0xd2c2, 0x00, 0 },
	{ 0xd2c3, 0x88, 0 },
	{ 0xd2c4, 0x85, 0 },
	{ 0xd2c5, 0x01, 0 },
	{ 0xd2c6, 0x00, 0 },
	{ 0xd2c7, 0x14, 0 },
	{ 0xd2c8, 0xbd, 0 },
	{ 0xd2c9, 0x68, 0 },
	{ 0xd2ca, 0x00, 0 },
	{ 0xd2cb, 0x00, 0 },
	{ 0xd2cc, 0x0c, 0 },
	{ 0xd2cd, 0x00, 0 },
	{ 0xd2ce, 0x00, 0 },
	{ 0xd2cf, 0x2c, 0 },
	{ 0xd2d0, 0xd4, 0 },
	{ 0xd2d1, 0x01, 0 },
	{ 0xd2d2, 0x58, 0 },
	{ 0xd2d3, 0x18, 0 },
	{ 0xd2d4, 0x84, 0 },
	{ 0xd2d5, 0x81, 0 },
	{ 0xd2d6, 0x00, 0 },
	{ 0xd2d7, 0x14, 0 },
	{ 0xd2d8, 0xbd, 0 },
	{ 0xd2d9, 0xa4, 0 },
	{ 0xd2da, 0x01, 0 },
	{ 0xd2db, 0x00, 0 },
	{ 0xd2dc, 0x10, 0 },
	{ 0xd2dd, 0x00, 0 },
	{ 0xd2de, 0x00, 0 },
	{ 0xd2df, 0x05, 0 },
	{ 0xd2e0, 0x84, 0 },
	{ 0xd2e1, 0xc1, 0 },
	{ 0xd2e2, 0x00, 0 },
	{ 0xd2e3, 0x18, 0 },
	{ 0xd2e4, 0x9c, 0 },
	{ 0xd2e5, 0xa0, 0 },
	{ 0xd2e6, 0x01, 0 },
	{ 0xd2e7, 0x00, 0 },
	{ 0xd2e8, 0xd4, 0 },
	{ 0xd2e9, 0x01, 0 },
	{ 0xd2ea, 0x28, 0 },
	{ 0xd2eb, 0x14, 0 },
	{ 0xd2ec, 0x84, 0 },
	{ 0xd2ed, 0xc1, 0 },
	{ 0xd2ee, 0x00, 0 },
	{ 0xd2ef, 0x18, 0 },
	{ 0xd2f0, 0xbd, 0 },
	{ 0xd2f1, 0x66, 0 },
	{ 0xd2f2, 0x00, 0 },
	{ 0xd2f3, 0x00, 0 },
	{ 0xd2f4, 0x0c, 0 },
	{ 0xd2f5, 0x00, 0 },
	{ 0xd2f6, 0x00, 0 },
	{ 0xd2f7, 0x20, 0 },
	{ 0xd2f8, 0x9d, 0 },
	{ 0xd2f9, 0x00, 0 },
	{ 0xd2fa, 0x00, 0 },
	{ 0xd2fb, 0x00, 0 },
	{ 0xd2fc, 0x84, 0 },
	{ 0xd2fd, 0x61, 0 },
	{ 0xd2fe, 0x00, 0 },
	{ 0xd2ff, 0x18, 0 },
	{ 0xd300, 0xbd, 0 },
	{ 0xd301, 0xa3, 0 },
	{ 0xd302, 0x01, 0 },
	{ 0xd303, 0x00, 0 },
	{ 0xd304, 0x10, 0 },
	{ 0xd305, 0x00, 0 },
	{ 0xd306, 0x00, 0 },
	{ 0xd307, 0x03, 0 },
	{ 0xd308, 0x9c, 0 },
	{ 0xd309, 0x80, 0 },
	{ 0xd30a, 0x01, 0 },
	{ 0xd30b, 0x00, 0 },
	{ 0xd30c, 0xd4, 0 },
	{ 0xd30d, 0x01, 0 },
	{ 0xd30e, 0x20, 0 },
	{ 0xd30f, 0x18, 0 },
	{ 0xd310, 0x18, 0 },
	{ 0xd311, 0x60, 0 },
	{ 0xd312, 0x80, 0 },
	{ 0xd313, 0x06, 0 },
	{ 0xd314, 0x85, 0 },
	{ 0xd315, 0x01, 0 },
	{ 0xd316, 0x00, 0 },
	{ 0xd317, 0x14, 0 },
	{ 0xd318, 0xa8, 0 },
	{ 0xd319, 0x83, 0 },
	{ 0xd31a, 0x38, 0 },
	{ 0xd31b, 0x29, 0 },
	{ 0xd31c, 0xa8, 0 },
	{ 0xd31d, 0xc3, 0 },
	{ 0xd31e, 0x40, 0 },
	{ 0xd31f, 0x08, 0 },
	{ 0xd320, 0x8c, 0 },
	{ 0xd321, 0x84, 0 },
	{ 0xd322, 0x00, 0 },
	{ 0xd323, 0x00, 0 },
	{ 0xd324, 0xa8, 0 },
	{ 0xd325, 0xa3, 0 },
	{ 0xd326, 0x38, 0 },
	{ 0xd327, 0x2a, 0 },
	{ 0xd328, 0xa8, 0 },
	{ 0xd329, 0xe3, 0 },
	{ 0xd32a, 0x40, 0 },
	{ 0xd32b, 0x09, 0 },
	{ 0xd32c, 0xe0, 0 },
	{ 0xd32d, 0x64, 0 },
	{ 0xd32e, 0x40, 0 },
	{ 0xd32f, 0x00, 0 },
	{ 0xd330, 0xd8, 0 },
	{ 0xd331, 0x06, 0 },
	{ 0xd332, 0x18, 0 },
	{ 0xd333, 0x00, 0 },
	{ 0xd334, 0x8c, 0 },
	{ 0xd335, 0x65, 0 },
	{ 0xd336, 0x00, 0 },
	{ 0xd337, 0x00, 0 },
	{ 0xd338, 0x84, 0 },
	{ 0xd339, 0x81, 0 },
	{ 0xd33a, 0x00, 0 },
	{ 0xd33b, 0x18, 0 },
	{ 0xd33c, 0xe3, 0 },
	{ 0xd33d, 0xe3, 0 },
	{ 0xd33e, 0x20, 0 },
	{ 0xd33f, 0x00, 0 },
	{ 0xd340, 0xd8, 0 },
	{ 0xd341, 0x07, 0 },
	{ 0xd342, 0xf8, 0 },
	{ 0xd343, 0x00, 0 },
	{ 0xd344, 0x03, 0 },
	{ 0xd345, 0xff, 0 },
	{ 0xd346, 0xff, 0 },
	{ 0xd347, 0x6f, 0 },
	{ 0xd348, 0x18, 0 },
	{ 0xd349, 0x60, 0 },
	{ 0xd34a, 0x00, 0 },
	{ 0xd34b, 0x01, 0 },
	{ 0xd34c, 0x0f, 0 },
	{ 0xd34d, 0xff, 0 },
	{ 0xd34e, 0xff, 0 },
	{ 0xd34f, 0x9d, 0 },
	{ 0xd350, 0x18, 0 },
	{ 0xd351, 0x60, 0 },
	{ 0xd352, 0x80, 0 },
	{ 0xd353, 0x06, 0 },
	{ 0xd354, 0x00, 0 },
	{ 0xd355, 0x00, 0 },
	{ 0xd356, 0x00, 0 },
	{ 0xd357, 0x11, 0 },
	{ 0xd358, 0xa8, 0 },
	{ 0xd359, 0x83, 0 },
	{ 0xd35a, 0x6e, 0 },
	{ 0xd35b, 0x43, 0 },
	{ 0xd35c, 0xe0, 0 },
	{ 0xd35d, 0x6c, 0 },
	{ 0xd35e, 0x28, 0 },
	{ 0xd35f, 0x02, 0 },
	{ 0xd360, 0xe0, 0 },
	{ 0xd361, 0x84, 0 },
	{ 0xd362, 0x28, 0 },
	{ 0xd363, 0x02, 0 },
	{ 0xd364, 0x07, 0 },
	{ 0xd365, 0xff, 0 },
	{ 0xd366, 0xf8, 0 },
	{ 0xd367, 0x30, 0 },
	{ 0xd368, 0xb8, 0 },
	{ 0xd369, 0x63, 0 },
	{ 0xd36a, 0x00, 0 },
	{ 0xd36b, 0x08, 0 },
	{ 0xd36c, 0x03, 0 },
	{ 0xd36d, 0xff, 0 },
	{ 0xd36e, 0xff, 0 },
	{ 0xd36f, 0xc0, 0 },
	{ 0xd370, 0x85, 0 },
	{ 0xd371, 0x4e, 0 },
	{ 0xd372, 0x00, 0 },
	{ 0xd373, 0x00, 0 },
	{ 0xd374, 0x03, 0 },
	{ 0xd375, 0xff, 0 },
	{ 0xd376, 0xff, 0 },
	{ 0xd377, 0xe7, 0 },
	{ 0xd378, 0xd4, 0 },
	{ 0xd379, 0x01, 0 },
	{ 0xd37a, 0x40, 0 },
	{ 0xd37b, 0x18, 0 },
	{ 0xd37c, 0x9c, 0 },
	{ 0xd37d, 0x60, 0 },
	{ 0xd37e, 0x00, 0 },
	{ 0xd37f, 0x00, 0 },
	{ 0xd380, 0x03, 0 },
	{ 0xd381, 0xff, 0 },
	{ 0xd382, 0xff, 0 },
	{ 0xd383, 0xdb, 0 },
	{ 0xd384, 0xd4, 0 },
	{ 0xd385, 0x01, 0 },
	{ 0xd386, 0x18, 0 },
	{ 0xd387, 0x14, 0 },
	{ 0xd388, 0x03, 0 },
	{ 0xd389, 0xff, 0 },
	{ 0xd38a, 0xff, 0 },
	{ 0xd38b, 0xce, 0 },
	{ 0xd38c, 0x9d, 0 },
	{ 0xd38d, 0x6b, 0 },
	{ 0xd38e, 0x00, 0 },
	{ 0xd38f, 0xff, 0 },
	{ 0xd390, 0x03, 0 },
	{ 0xd391, 0xff, 0 },
	{ 0xd392, 0xff, 0 },
	{ 0xd393, 0xc6, 0 },
	{ 0xd394, 0x9c, 0 },
	{ 0xd395, 0x63, 0 },
	{ 0xd396, 0x00, 0 },
	{ 0xd397, 0xff, 0 },
	{ 0xd398, 0xa8, 0 },
	{ 0xd399, 0xe3, 0 },
	{ 0xd39a, 0x38, 0 },
	{ 0xd39b, 0x0f, 0 },
	{ 0xd39c, 0x8c, 0 },
	{ 0xd39d, 0x84, 0 },
	{ 0xd39e, 0x00, 0 },
	{ 0xd39f, 0x00, 0 },
	{ 0xd3a0, 0xa8, 0 },
	{ 0xd3a1, 0xa3, 0 },
	{ 0xd3a2, 0x38, 0 },
	{ 0xd3a3, 0x0e, 0 },
	{ 0xd3a4, 0xa8, 0 },
	{ 0xd3a5, 0xc3, 0 },
	{ 0xd3a6, 0x6e, 0 },
	{ 0xd3a7, 0x42, 0 },
	{ 0xd3a8, 0xd8, 0 },
	{ 0xd3a9, 0x07, 0 },
	{ 0xd3aa, 0x20, 0 },
	{ 0xd3ab, 0x00, 0 },
	{ 0xd3ac, 0x8c, 0 },
	{ 0xd3ad, 0x66, 0 },
	{ 0xd3ae, 0x00, 0 },
	{ 0xd3af, 0x00, 0 },
	{ 0xd3b0, 0xd8, 0 },
	{ 0xd3b1, 0x05, 0 },
	{ 0xd3b2, 0x18, 0 },
	{ 0xd3b3, 0x00, 0 },
	{ 0xd3b4, 0x85, 0 },
	{ 0xd3b5, 0x21, 0 },
	{ 0xd3b6, 0x00, 0 },
	{ 0xd3b7, 0x00, 0 },
	{ 0xd3b8, 0x85, 0 },
	{ 0xd3b9, 0x41, 0 },
	{ 0xd3ba, 0x00, 0 },
	{ 0xd3bb, 0x04, 0 },
	{ 0xd3bc, 0x85, 0 },
	{ 0xd3bd, 0x81, 0 },
	{ 0xd3be, 0x00, 0 },
	{ 0xd3bf, 0x08, 0 },
	{ 0xd3c0, 0x85, 0 },
	{ 0xd3c1, 0xc1, 0 },
	{ 0xd3c2, 0x00, 0 },
	{ 0xd3c3, 0x0c, 0 },
	{ 0xd3c4, 0x86, 0 },
	{ 0xd3c5, 0x01, 0 },
	{ 0xd3c6, 0x00, 0 },
	{ 0xd3c7, 0x10, 0 },
	{ 0xd3c8, 0x44, 0 },
	{ 0xd3c9, 0x00, 0 },
	{ 0xd3ca, 0x48, 0 },
	{ 0xd3cb, 0x00, 0 },
	{ 0xd3cc, 0x9c, 0 },
	{ 0xd3cd, 0x21, 0 },
	{ 0xd3ce, 0x00, 0 },
	{ 0xd3cf, 0x1c, 0 },
	{ 0xd3d0, 0x9c, 0 },
	{ 0xd3d1, 0x21, 0 },
	{ 0xd3d2, 0xff, 0 },
	{ 0xd3d3, 0xfc, 0 },
	{ 0xd3d4, 0xd4, 0 },
	{ 0xd3d5, 0x01, 0 },
	{ 0xd3d6, 0x48, 0 },
	{ 0xd3d7, 0x00, 0 },
	{ 0xd3d8, 0x18, 0 },
	{ 0xd3d9, 0x60, 0 },
	{ 0xd3da, 0x00, 0 },
	{ 0xd3db, 0x01, 0 },
	{ 0xd3dc, 0xa8, 0 },
	{ 0xd3dd, 0x63, 0 },
	{ 0xd3de, 0x07, 0 },
	{ 0xd3df, 0x80, 0 },
	{ 0xd3e0, 0x8c, 0 },
	{ 0xd3e1, 0x63, 0 },
	{ 0xd3e2, 0x00, 0 },
	{ 0xd3e3, 0x68, 0 },
	{ 0xd3e4, 0xbc, 0 },
	{ 0xd3e5, 0x03, 0 },
	{ 0xd3e6, 0x00, 0 },
	{ 0xd3e7, 0x00, 0 },
	{ 0xd3e8, 0x10, 0 },
	{ 0xd3e9, 0x00, 0 },
	{ 0xd3ea, 0x00, 0 },
	{ 0xd3eb, 0x0c, 0 },
	{ 0xd3ec, 0x15, 0 },
	{ 0xd3ed, 0x00, 0 },
	{ 0xd3ee, 0x00, 0 },
	{ 0xd3ef, 0x00, 0 },
	{ 0xd3f0, 0x07, 0 },
	{ 0xd3f1, 0xff, 0 },
	{ 0xd3f2, 0xd9, 0 },
	{ 0xd3f3, 0x98, 0 },
	{ 0xd3f4, 0x15, 0 },
	{ 0xd3f5, 0x00, 0 },
	{ 0xd3f6, 0x00, 0 },
	{ 0xd3f7, 0x00, 0 },
	{ 0xd3f8, 0x18, 0 },
	{ 0xd3f9, 0x60, 0 },
	{ 0xd3fa, 0x80, 0 },
	{ 0xd3fb, 0x06, 0 },
	{ 0xd3fc, 0xa8, 0 },
	{ 0xd3fd, 0x63, 0 },
	{ 0xd3fe, 0xc4, 0 },
	{ 0xd3ff, 0xb8, 0 },
	{ 0xd400, 0x8c, 0 },
	{ 0xd401, 0x63, 0 },
	{ 0xd402, 0x00, 0 },
	{ 0xd403, 0x00, 0 },
	{ 0xd404, 0xbc, 0 },
	{ 0xd405, 0x23, 0 },
	{ 0xd406, 0x00, 0 },
	{ 0xd407, 0x01, 0 },
	{ 0xd408, 0x10, 0 },
	{ 0xd409, 0x00, 0 },
	{ 0xd40a, 0x00, 0 },
	{ 0xd40b, 0x25, 0 },
	{ 0xd40c, 0x9d, 0 },
	{ 0xd40d, 0x00, 0 },
	{ 0xd40e, 0x00, 0 },
	{ 0xd40f, 0x00, 0 },
	{ 0xd410, 0x00, 0 },
	{ 0xd411, 0x00, 0 },
	{ 0xd412, 0x00, 0 },
	{ 0xd413, 0x0b, 0 },
	{ 0xd414, 0xb8, 0 },
	{ 0xd415, 0xe8, 0 },
	{ 0xd416, 0x00, 0 },
	{ 0xd417, 0x02, 0 },
	{ 0xd418, 0x07, 0 },
	{ 0xd419, 0xff, 0 },
	{ 0xd41a, 0xd6, 0 },
	{ 0xd41b, 0x24, 0 },
	{ 0xd41c, 0x15, 0 },
	{ 0xd41d, 0x00, 0 },
	{ 0xd41e, 0x00, 0 },
	{ 0xd41f, 0x00, 0 },
	{ 0xd420, 0x18, 0 },
	{ 0xd421, 0x60, 0 },
	{ 0xd422, 0x80, 0 },
	{ 0xd423, 0x06, 0 },
	{ 0xd424, 0xa8, 0 },
	{ 0xd425, 0x63, 0 },
	{ 0xd426, 0xc4, 0 },
	{ 0xd427, 0xb8, 0 },
	{ 0xd428, 0x8c, 0 },
	{ 0xd429, 0x63, 0 },
	{ 0xd42a, 0x00, 0 },
	{ 0xd42b, 0x00, 0 },
	{ 0xd42c, 0xbc, 0 },
	{ 0xd42d, 0x23, 0 },
	{ 0xd42e, 0x00, 0 },
	{ 0xd42f, 0x01, 0 },
	{ 0xd430, 0x10, 0 },
	{ 0xd431, 0x00, 0 },
	{ 0xd432, 0x00, 0 },
	{ 0xd433, 0x1b, 0 },
	{ 0xd434, 0x9d, 0 },
	{ 0xd435, 0x00, 0 },
	{ 0xd436, 0x00, 0 },
	{ 0xd437, 0x00, 0 },
	{ 0xd438, 0xb8, 0 },
	{ 0xd439, 0xe8, 0 },
	{ 0xd43a, 0x00, 0 },
	{ 0xd43b, 0x02, 0 },
	{ 0xd43c, 0x9c, 0 },
	{ 0xd43d, 0xc0, 0 },
	{ 0xd43e, 0x00, 0 },
	{ 0xd43f, 0x00, 0 },
	{ 0xd440, 0x18, 0 },
	{ 0xd441, 0xa0, 0 },
	{ 0xd442, 0x80, 0 },
	{ 0xd443, 0x06, 0 },
	{ 0xd444, 0xe0, 0 },
	{ 0xd445, 0x67, 0 },
	{ 0xd446, 0x30, 0 },
	{ 0xd447, 0x00, 0 },
	{ 0xd448, 0xa8, 0 },
	{ 0xd449, 0xa5, 0 },
	{ 0xd44a, 0xce, 0 },
	{ 0xd44b, 0xb0, 0 },
	{ 0xd44c, 0x19, 0 },
	{ 0xd44d, 0x60, 0 },
	{ 0xd44e, 0x00, 0 },
	{ 0xd44f, 0x01, 0 },
	{ 0xd450, 0xa9, 0 },
	{ 0xd451, 0x6b, 0 },
	{ 0xd452, 0x06, 0 },
	{ 0xd453, 0x14, 0 },
	{ 0xd454, 0xe0, 0 },
	{ 0xd455, 0x83, 0 },
	{ 0xd456, 0x28, 0 },
	{ 0xd457, 0x00, 0 },
	{ 0xd458, 0x9c, 0 },
	{ 0xd459, 0xc6, 0 },
	{ 0xd45a, 0x00, 0 },
	{ 0xd45b, 0x01, 0 },
	{ 0xd45c, 0xe0, 0 },
	{ 0xd45d, 0x63, 0 },
	{ 0xd45e, 0x18, 0 },
	{ 0xd45f, 0x00, 0 },
	{ 0xd460, 0x8c, 0 },
	{ 0xd461, 0x84, 0 },
	{ 0xd462, 0x00, 0 },
	{ 0xd463, 0x00, 0 },
	{ 0xd464, 0xe0, 0 },
	{ 0xd465, 0xa3, 0 },
	{ 0xd466, 0x58, 0 },
	{ 0xd467, 0x00, 0 },
	{ 0xd468, 0xa4, 0 },
	{ 0xd469, 0xc6, 0 },
	{ 0xd46a, 0x00, 0 },
	{ 0xd46b, 0xff, 0 },
	{ 0xd46c, 0xb8, 0 },
	{ 0xd46d, 0x64, 0 },
	{ 0xd46e, 0x00, 0 },
	{ 0xd46f, 0x18, 0 },
	{ 0xd470, 0xbc, 0 },
	{ 0xd471, 0x46, 0 },
	{ 0xd472, 0x00, 0 },
	{ 0xd473, 0x03, 0 },
	{ 0xd474, 0x94, 0 },
	{ 0xd475, 0x85, 0 },
	{ 0xd476, 0x00, 0 },
	{ 0xd477, 0x00, 0 },
	{ 0xd478, 0xb8, 0 },
	{ 0xd479, 0x63, 0 },
	{ 0xd47a, 0x00, 0 },
	{ 0xd47b, 0x98, 0 },
	{ 0xd47c, 0xe0, 0 },
	{ 0xd47d, 0x64, 0 },
	{ 0xd47e, 0x18, 0 },
	{ 0xd47f, 0x00, 0 },
	{ 0xd480, 0x0f, 0 },
	{ 0xd481, 0xff, 0 },
	{ 0xd482, 0xff, 0 },
	{ 0xd483, 0xf0, 0 },
	{ 0xd484, 0xdc, 0 },
	{ 0xd485, 0x05, 0 },
	{ 0xd486, 0x18, 0 },
	{ 0xd487, 0x00, 0 },
	{ 0xd488, 0x9c, 0 },
	{ 0xd489, 0x68, 0 },
	{ 0xd48a, 0x00, 0 },
	{ 0xd48b, 0x01, 0 },
	{ 0xd48c, 0xa5, 0 },
	{ 0xd48d, 0x03, 0 },
	{ 0xd48e, 0x00, 0 },
	{ 0xd48f, 0xff, 0 },
	{ 0xd490, 0xbc, 0 },
	{ 0xd491, 0x48, 0 },
	{ 0xd492, 0x00, 0 },
	{ 0xd493, 0x01, 0 },
	{ 0xd494, 0x0f, 0 },
	{ 0xd495, 0xff, 0 },
	{ 0xd496, 0xff, 0 },
	{ 0xd497, 0xea, 0 },
	{ 0xd498, 0xb8, 0 },
	{ 0xd499, 0xe8, 0 },
	{ 0xd49a, 0x00, 0 },
	{ 0xd49b, 0x02, 0 },
	{ 0xd49c, 0x18, 0 },
	{ 0xd49d, 0x60, 0 },
	{ 0xd49e, 0x00, 0 },
	{ 0xd49f, 0x01, 0 },
	{ 0xd4a0, 0xa8, 0 },
	{ 0xd4a1, 0x63, 0 },
	{ 0xd4a2, 0x06, 0 },
	{ 0xd4a3, 0x14, 0 },
	{ 0xd4a4, 0x07, 0 },
	{ 0xd4a5, 0xff, 0 },
	{ 0xd4a6, 0xe4, 0 },
	{ 0xd4a7, 0x05, 0 },
	{ 0xd4a8, 0x9c, 0 },
	{ 0xd4a9, 0x83, 0 },
	{ 0xd4aa, 0x00, 0 },
	{ 0xd4ab, 0x10, 0 },
	{ 0xd4ac, 0x85, 0 },
	{ 0xd4ad, 0x21, 0 },
	{ 0xd4ae, 0x00, 0 },
	{ 0xd4af, 0x00, 0 },
	{ 0xd4b0, 0x44, 0 },
	{ 0xd4b1, 0x00, 0 },
	{ 0xd4b2, 0x48, 0 },
	{ 0xd4b3, 0x00, 0 },
	{ 0xd4b4, 0x9c, 0 },
	{ 0xd4b5, 0x21, 0 },
	{ 0xd4b6, 0x00, 0 },
	{ 0xd4b7, 0x04, 0 },
	{ 0xd4b8, 0x18, 0 },
	{ 0xd4b9, 0x60, 0 },
	{ 0xd4ba, 0x00, 0 },
	{ 0xd4bb, 0x01, 0 },
	{ 0xd4bc, 0x9c, 0 },
	{ 0xd4bd, 0x80, 0 },
	{ 0xd4be, 0xff, 0 },
	{ 0xd4bf, 0xff, 0 },
	{ 0xd4c0, 0xa8, 0 },
	{ 0xd4c1, 0x63, 0 },
	{ 0xd4c2, 0x09, 0 },
	{ 0xd4c3, 0xef, 0 },
	{ 0xd4c4, 0xd8, 0 },
	{ 0xd4c5, 0x03, 0 },
	{ 0xd4c6, 0x20, 0 },
	{ 0xd4c7, 0x00, 0 },
	{ 0xd4c8, 0x18, 0 },
	{ 0xd4c9, 0x60, 0 },
	{ 0xd4ca, 0x80, 0 },
	{ 0xd4cb, 0x06, 0 },
	{ 0xd4cc, 0xa8, 0 },
	{ 0xd4cd, 0x63, 0 },
	{ 0xd4ce, 0xc9, 0 },
	{ 0xd4cf, 0xef, 0 },
	{ 0xd4d0, 0xd8, 0 },
	{ 0xd4d1, 0x03, 0 },
	{ 0xd4d2, 0x20, 0 },
	{ 0xd4d3, 0x00, 0 },
	{ 0xd4d4, 0x44, 0 },
	{ 0xd4d5, 0x00, 0 },
	{ 0xd4d6, 0x48, 0 },
	{ 0xd4d7, 0x00, 0 },
	{ 0xd4d8, 0x15, 0 },
	{ 0xd4d9, 0x00, 0 },
	{ 0xd4da, 0x00, 0 },
	{ 0xd4db, 0x00, 0 },
	{ 0xd4dc, 0x18, 0 },
	{ 0xd4dd, 0x80, 0 },
	{ 0xd4de, 0x00, 0 },
	{ 0xd4df, 0x01, 0 },
	{ 0xd4e0, 0xa8, 0 },
	{ 0xd4e1, 0x84, 0 },
	{ 0xd4e2, 0x0a, 0 },
	{ 0xd4e3, 0x12, 0 },
	{ 0xd4e4, 0x8c, 0 },
	{ 0xd4e5, 0x64, 0 },
	{ 0xd4e6, 0x00, 0 },
	{ 0xd4e7, 0x00, 0 },
	{ 0xd4e8, 0xbc, 0 },
	{ 0xd4e9, 0x03, 0 },
	{ 0xd4ea, 0x00, 0 },
	{ 0xd4eb, 0x00, 0 },
	{ 0xd4ec, 0x13, 0 },
	{ 0xd4ed, 0xff, 0 },
	{ 0xd4ee, 0xff, 0 },
	{ 0xd4ef, 0xfe, 0 },
	{ 0xd4f0, 0x15, 0 },
	{ 0xd4f1, 0x00, 0 },
	{ 0xd4f2, 0x00, 0 },
	{ 0xd4f3, 0x00, 0 },
	{ 0xd4f4, 0x44, 0 },
	{ 0xd4f5, 0x00, 0 },
	{ 0xd4f6, 0x48, 0 },
	{ 0xd4f7, 0x00, 0 },
	{ 0xd4f8, 0x15, 0 },
	{ 0xd4f9, 0x00, 0 },
	{ 0xd4fa, 0x00, 0 },
	{ 0xd4fb, 0x00, 0 },
	{ 0xd4fc, 0x00, 0 },
	{ 0xd4fd, 0x00, 0 },
	{ 0xd4fe, 0x00, 0 },
	{ 0xd4ff, 0x00, 0 },
	{ 0xd500, 0x00, 0 },
	{ 0xd501, 0x00, 0 },
	{ 0xd502, 0x00, 0 },
	{ 0xd503, 0x00, 0 },
	{ 0x6f0e, 0x33, 0 },
	{ 0x6f0f, 0x33, 0 },
	{ 0x460e, 0x08, 0 },
	{ 0x460f, 0x01, 0 },
	{ 0x4610, 0x00, 0 },
	{ 0x4611, 0x01, 0 },
	{ 0x4612, 0x00, 0 },
	{ 0x4613, 0x01, 0 },
	{ 0x4605, 0x08, 0 },
	{ 0x4608, 0x00, 0 },
	{ 0x4609, 0x08, 0 },
	{ 0x6804, 0x00, 0 },
	{ 0x6805, 0x06, 0 },
	{ 0x6806, 0x00, 0 },
	{ 0x5120, 0x00, 0 },
	{ 0x3510, 0x00, 0 },
	{ 0x3504, 0x00, 0 },
	{ 0x6800, 0x00, 0 },
	{ 0x6f0d, 0x0f, 0 },
	{ 0x5000, 0xff, 0 },
	{ 0x5001, 0xbf, 0 },
	{ 0x5002, 0x7e, 0 },
	{ 0x5003, 0x0c, 0 },
	{ 0x503d, 0x00, 0 },
	{ 0xc450, 0x01, 0 },
	{ 0xc452, 0x04, 0 },
	{ 0xc453, 0x00, 0 },
	{ 0xc454, 0x00, 0 },
	{ 0xc455, 0x00, 0 },
	{ 0xc456, 0x00, 0 },
	{ 0xc457, 0x00, 0 },
	{ 0xc458, 0x00, 0 },
	{ 0xc459, 0x00, 0 },
	{ 0xc45b, 0x00, 0 },
	{ 0xc45c, 0x00, 0 },
	{ 0xc45d, 0x00, 0 },
	{ 0xc45e, 0x00, 0 },
	{ 0xc45f, 0x00, 0 },
	{ 0xc460, 0x00, 0 },
	{ 0xc461, 0x01, 0 },
	{ 0xc462, 0x01, 0 },
	{ 0xc464, 0x88, 0 },
	{ 0xc465, 0x00, 0 },
	{ 0xc466, 0x8a, 0 },
	{ 0xc467, 0x00, 0 },
	{ 0xc468, 0x86, 0 },
	{ 0xc469, 0x00, 0 },
	{ 0xc46a, 0x40, 0 },
	{ 0xc46b, 0x50, 0 },
	{ 0xc46c, 0x30, 0 },
	{ 0xc46d, 0x28, 0 },
	{ 0xc46e, 0x60, 0 },
	{ 0xc46f, 0x40, 0 },
	{ 0xc47c, 0x01, 0 },
	{ 0xc47d, 0x38, 0 },
	{ 0xc47e, 0x00, 0 },
	{ 0xc47f, 0x00, 0 },
	{ 0xc480, 0x00, 0 },
	{ 0xc481, 0xff, 0 },
	{ 0xc482, 0x00, 0 },
	{ 0xc483, 0x40, 0 },
	{ 0xc484, 0x00, 0 },
	{ 0xc485, 0x18, 0 },
	{ 0xc486, 0x00, 0 },
	{ 0xc487, 0x18, 0 },
	{ 0xc488, 0x34, 0 },
	{ 0xc489, 0x00, 0 },
	{ 0xc48a, 0x34, 0 },
	{ 0xc48b, 0x00, 0 },
	{ 0xc48c, 0x00, 0 },
	{ 0xc48d, 0x04, 0 },
	{ 0xc48e, 0x00, 0 },
	{ 0xc48f, 0x04, 0 },
	{ 0xc490, 0x07, 0 },
	{ 0xc492, 0x20, 0 },
	{ 0xc493, 0x08, 0 },
	{ 0xc498, 0x02, 0 },
	{ 0xc499, 0x00, 0 },
	{ 0xc49a, 0x02, 0 },
	{ 0xc49b, 0x00, 0 },
	{ 0xc49c, 0x02, 0 },
	{ 0xc49d, 0x00, 0 },
	{ 0xc49e, 0x02, 0 },
	{ 0xc49f, 0x60, 0 },
	{ 0xc4a0, 0x03, 0 },
	{ 0xc4a1, 0x00, 0 },
	{ 0xc4a2, 0x04, 0 },
	{ 0xc4a3, 0x00, 0 },
	{ 0xc4a4, 0x00, 0 },
	{ 0xc4a5, 0x10, 0 },
	{ 0xc4a6, 0x00, 0 },
	{ 0xc4a7, 0x40, 0 },
	{ 0xc4a8, 0x00, 0 },
	{ 0xc4a9, 0x80, 0 },
	{ 0xc4aa, 0x0d, 0 },
	{ 0xc4ab, 0x00, 0 },
	{ 0xc4ac, 0x0f, 0 },
	{ 0xc4ad, 0xc0, 0 },
	{ 0xc4b4, 0x01, 0 },
	{ 0xc4b5, 0x01, 0 },
	{ 0xc4b6, 0x00, 0 },
	{ 0xc4b7, 0x01, 0 },
	{ 0xc4b8, 0x00, 0 },
	{ 0xc4b9, 0x01, 0 },
	{ 0xc4ba, 0x01, 0 },
	{ 0xc4bb, 0x00, 0 },
	{ 0xc4bc, 0x01, 0 },
	{ 0xc4bd, 0x60, 0 },
	{ 0xc4be, 0x02, 0 },
	{ 0xc4bf, 0x33, 0 },
	{ 0xc4c8, 0x03, 0 },
	{ 0xc4c9, 0xd0, 0 },
	{ 0xc4ca, 0x0e, 0 },
	{ 0xc4cb, 0x00, 0 },
	{ 0xc4cc, 0x10, 0 },
	{ 0xc4cd, 0x18, 0 },
	{ 0xc4ce, 0x10, 0 },
	{ 0xc4cf, 0x18, 0 },
	{ 0xc4d0, 0x04, 0 },
	{ 0xc4d1, 0x80, 0 },
	{ 0xc4e0, 0x04, 0 },
	{ 0xc4e1, 0x02, 0 },
	{ 0xc4e2, 0x01, 0 },
	{ 0xc4e4, 0x10, 0 },
	{ 0xc4e5, 0x20, 0 },
	{ 0xc4e6, 0x30, 0 },
	{ 0xc4e7, 0x40, 0 },
	{ 0xc4e8, 0x50, 0 },
	{ 0xc4e9, 0x60, 0 },
	{ 0xc4ea, 0x70, 0 },
	{ 0xc4eb, 0x80, 0 },
	{ 0xc4ec, 0x90, 0 },
	{ 0xc4ed, 0xa0, 0 },
	{ 0xc4ee, 0xb0, 0 },
	{ 0xc4ef, 0xc0, 0 },
	{ 0xc4f0, 0xd0, 0 },
	{ 0xc4f1, 0xe0, 0 },
	{ 0xc4f2, 0xf0, 0 },
	{ 0xc4f3, 0x80, 0 },
	{ 0xc4f4, 0x00, 0 },
	{ 0xc4f5, 0x20, 0 },
	{ 0xc4f6, 0x02, 0 },
	{ 0xc4f7, 0x00, 0 },
	{ 0xc4f8, 0x04, 0 },
	{ 0xc4f9, 0x0b, 0 },
	{ 0xc4fa, 0x00, 0 },
	{ 0xc4fb, 0x00, 0 },
	{ 0xc4fc, 0x01, 0 },
	{ 0xc4fd, 0x00, 0 },
	{ 0xc4fe, 0x04, 0 },
	{ 0xc4ff, 0x02, 0 },
	{ 0xc500, 0x48, 0 },
	{ 0xc501, 0x74, 0 },
	{ 0xc502, 0x58, 0 },
	{ 0xc503, 0x80, 0 },
	{ 0xc504, 0x05, 0 },
	{ 0xc505, 0x80, 0 },
	{ 0xc506, 0x03, 0 },
	{ 0xc507, 0x80, 0 },
	{ 0xc508, 0x01, 0 },
	{ 0xc509, 0xc0, 0 },
	{ 0xc50a, 0x01, 0 },
	{ 0xc50b, 0xa0, 0 },
	{ 0xc50c, 0x01, 0 },
	{ 0xc50d, 0x2c, 0 },
	{ 0xc50e, 0x01, 0 },
	{ 0xc50f, 0x0a, 0 },
	{ 0xc510, 0x00, 0 },
	{ 0xc511, 0x01, 0 },
	{ 0xc512, 0x01, 0 },
	{ 0xc513, 0x80, 0 },
	{ 0xc514, 0x04, 0 },
	{ 0xc515, 0x00, 0 },
	{ 0xc518, 0x03, 0 },
	{ 0xc519, 0x48, 0 },
	{ 0xc51a, 0x07, 0 },
	{ 0xc51b, 0x70, 0 },
	{ 0xc2e0, 0x00, 0 },
	{ 0xc2e1, 0x51, 0 },
	{ 0xc2e2, 0x00, 0 },
	{ 0xc2e3, 0xd6, 0 },
	{ 0xc2e4, 0x01, 0 },
	{ 0xc2e5, 0x5e, 0 },
	{ 0xc2e9, 0x01, 0 },
	{ 0xc2ea, 0x7a, 0 },
	{ 0xc2eb, 0x90, 0 },
	{ 0xc2ed, 0x00, 0 },
	{ 0xc2ee, 0x7a, 0 },
	{ 0xc2ef, 0x64, 0 },
	{ 0xc308, 0x00, 0 },
	{ 0xc309, 0x00, 0 },
	{ 0xc30a, 0x00, 0 },
	{ 0xc30c, 0x00, 0 },
	{ 0xc30d, 0x01, 0 },
	{ 0xc30e, 0x00, 0 },
	{ 0xc30f, 0x00, 0 },
	{ 0xc310, 0x01, 0 },
	{ 0xc311, 0x60, 0 },
	{ 0xc312, 0xff, 0 },
	{ 0xc313, 0x08, 0 },
	{ 0xc314, 0x01, 0 },
	{ 0xc315, 0x7f, 0 },
	{ 0xc316, 0xff, 0 },
	{ 0xc317, 0x0b, 0 },
	{ 0xc318, 0x00, 0 },
	{ 0xc319, 0x0c, 0 },
	{ 0xc31a, 0x00, 0 },
	{ 0xc31b, 0xe0, 0 },
	{ 0xc31c, 0x00, 0 },
	{ 0xc31d, 0x14, 0 },
	{ 0xc31e, 0x00, 0 },
	{ 0xc31f, 0xc5, 0 },
	{ 0xc320, 0xff, 0 },
	{ 0xc321, 0x4b, 0 },
	{ 0xc322, 0xff, 0 },
	{ 0xc323, 0xf0, 0 },
	{ 0xc324, 0xff, 0 },
	{ 0xc325, 0xe8, 0 },
	{ 0xc326, 0x00, 0 },
	{ 0xc327, 0x46, 0 },
	{ 0xc328, 0xff, 0 },
	{ 0xc329, 0xd2, 0 },
	{ 0xc32a, 0xff, 0 },
	{ 0xc32b, 0xe4, 0 },
	{ 0xc32c, 0xff, 0 },
	{ 0xc32d, 0xbb, 0 },
	{ 0xc32e, 0x00, 0 },
	{ 0xc32f, 0x61, 0 },
	{ 0xc330, 0xff, 0 },
	{ 0xc331, 0xf9, 0 },
	{ 0xc332, 0x00, 0 },
	{ 0xc333, 0xd9, 0 },
	{ 0xc334, 0x00, 0 },
	{ 0xc335, 0x2e, 0 },
	{ 0xc336, 0x00, 0 },
	{ 0xc337, 0xb1, 0 },
	{ 0xc338, 0xff, 0 },
	{ 0xc339, 0x64, 0 },
	{ 0xc33a, 0xff, 0 },
	{ 0xc33b, 0xeb, 0 },
	{ 0xc33c, 0xff, 0 },
	{ 0xc33d, 0xe8, 0 },
	{ 0xc33e, 0x00, 0 },
	{ 0xc33f, 0x48, 0 },
	{ 0xc340, 0xff, 0 },
	{ 0xc341, 0xd0, 0 },
	{ 0xc342, 0xff, 0 },
	{ 0xc343, 0xed, 0 },
	{ 0xc344, 0xff, 0 },
	{ 0xc345, 0xad, 0 },
	{ 0xc346, 0x00, 0 },
	{ 0xc347, 0x66, 0 },
	{ 0xc348, 0x01, 0 },
	{ 0xc349, 0x00, 0 },
	{ 0x6700, 0x04, 0 },
	{ 0x6701, 0x7b, 0 },
	{ 0x6702, 0xfd, 0 },
	{ 0x6703, 0xf9, 0 },
	{ 0x6704, 0x3d, 0 },
	{ 0x6705, 0x71, 0 },
	{ 0x6706, 0x78, 0 },
	{ 0x6708, 0x05, 0 },
	{ 0x6f06, 0x6f, 0 },
	{ 0x6f07, 0x00, 0 },
	{ 0x6f0a, 0x6f, 0 },
	{ 0x6f0b, 0x00, 0 },
	{ 0x6f00, 0x03, 0 },
	{ 0xc34c, 0x01, 0 },
	{ 0xc34d, 0x00, 0 },
	{ 0xc34e, 0x46, 0 },
	{ 0xc34f, 0x55, 0 },
	{ 0xc350, 0x00, 0 },
	{ 0xc351, 0x40, 0 },
	{ 0xc352, 0x00, 0 },
	{ 0xc353, 0xff, 0 },
	{ 0xc354, 0x04, 0 },
	{ 0xc355, 0x08, 0 },
	{ 0xc356, 0x01, 0 },
	{ 0xc357, 0xef, 0 },
	{ 0xc358, 0x30, 0 },
	{ 0xc359, 0x01, 0 },
	{ 0xc35a, 0x64, 0 },
	{ 0xc35b, 0x46, 0 },
	{ 0xc35c, 0x00, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x3042, 0xf0, 0 },
	{ 0x301b, 0xf0, 0 },
	{ 0x301c, 0xf0, 0 },
	{ 0x301a, 0xf0, 0 },
	{ 0xceb0, 0x00, 0 },
	{ 0xceb1, 0x00, 0 },
	{ 0xceb2, 0x00, 0 },
	{ 0xceb3, 0x00, 0 },
	{ 0xceb4, 0x00, 0 },
	{ 0xceb5, 0x00, 0 },
	{ 0xceb6, 0x00, 0 },
	{ 0xceb7, 0x00, 0 },
	{ 0xc4bc, 0x01, 0 },
	{ 0xc4bd, 0x60, 0 },

	{ 0x4709, 0x10, 0 },/* dvp swap */
	{ 0x4300, 0x3a, 0 },/* YUV order UYVY */
	{ 0x3832, 0x01, 0 },/* fsin */
	{ 0x3833, 0x1A, 0 },
	{ 0x3834, 0x03, 0 },
	{ 0x3835, 0x48, 0 },
	{ 0x302E, 0x01, 0 },
};

struct ov10635_mode_info {
	enum ov10635_mode mode;
	u32 width;
	u32 height;
	struct reg_value *init_data_ptr;
	u32 init_data_size;
};

static struct reg_value  ov10635_setting_30fps_WXGA_1280_800[] = {
	{ 0x3024, 0x01, 0 },
	{ 0x3003, 0x20, 0 },
	{ 0x3004, 0x21, 0 },
	{ 0x3005, 0x20, 0 },
	{ 0x3006, 0x91, 0 },
	/* 1280x800 */
	{ 0x3808, 0x05, 0 },
	{ 0x3809, 0x00, 0 },
	{ 0x380a, 0x03, 0 },
	{ 0x380b, 0x20, 0 },
};

static struct reg_value  ov10635_setting_30fps_720P_1280_720[] = {
	{ 0x3024, 0x01, 0 },
	{ 0x3003, 0x20, 0 },
	{ 0x3004, 0x21, 0 },
	{ 0x3005, 0x20, 0 },
	{ 0x3006, 0x91, 0 },
	/* 1280x720 */
	{ 0x3808, 0x05, 0 },
	{ 0x3809, 0x00, 0 },
	{ 0x380a, 0x02, 0 },
	{ 0x380b, 0xD0, 0 },
};

static struct reg_value  ov10635_setting_30fps_WVGA_752_480[] = {
	{ 0x3024, 0x01, 0 },
	{ 0x3003, 0x20, 0 },
	{ 0x3004, 0x21, 0 },
	{ 0x3005, 0x20, 0 },
	{ 0x3006, 0x91, 0 },
	/* 752x480 */
	{ 0x3808, 0x02, 0 },
	{ 0x3809, 0xF0, 0 },
	{ 0x380a, 0x01, 0 },
	{ 0x380b, 0xE0, 0 },
};

static struct reg_value  ov10635_setting_30fps_VGA_640_480[] = {
	{ 0x3024, 0x01, 0 },
	{ 0x3003, 0x20, 0 },
	{ 0x3004, 0x21, 0 },
	{ 0x3005, 0x20, 0 },
	{ 0x3006, 0x91, 0 },
	/* 640x480 */
	{ 0x3808, 0x02, 0 },
	{ 0x3809, 0x80, 0 },
	{ 0x380a, 0x01, 0 },
	{ 0x380b, 0xE0, 0 },
};

static struct reg_value  ov10635_setting_30fps_CIF_352_288[] = {
	{ 0x3024, 0x01, 0 },
	{ 0x3003, 0x20, 0 },
	{ 0x3004, 0x21, 0 },
	{ 0x3005, 0x20, 0 },
	{ 0x3006, 0x91, 0 },
	/* 352x288 */
	{ 0x3808, 0x01, 0 },
	{ 0x3809, 0x60, 0 },
	{ 0x380a, 0x01, 0 },
	{ 0x380b, 0x20, 0 },
};

static struct reg_value  ov10635_setting_30fps_QVGA_320_240[] = {
	{ 0x3024, 0x01, 0 },
	{ 0x3003, 0x20, 0 },
	{ 0x3004, 0x21, 0 },
	{ 0x3005, 0x20, 0 },
	{ 0x3006, 0x91, 0 },
	/* 320x240 */
	{ 0x3808, 0x01, 0 },
	{ 0x3809, 0x40, 0 },
	{ 0x380a, 0x00, 0 },
	{ 0x380b, 0xF0, 0 },
};

static struct ov10635_mode_info ov10635_mode_info_data[2][ov10635_mode_MAX + 1] = {
	/* 15fps not support */
	{
		{ ov10635_mode_WXGA_1280_800, 0, 0, NULL, 0 },
		{ ov10635_mode_720P_1280_720, 0, 0, NULL, 0 },
		{ ov10635_mode_WVGA_752_480, 0, 0, NULL, 0 },
		{ ov10635_mode_VGA_640_480, 0, 0, NULL, 0 },
		{ ov10635_mode_CIF_352_288, 0, 0, NULL, 0},
		{ ov10635_mode_QVGA_320_240, 0, 0, NULL, 0},
	},
	/* 30fps */
	{
		{ ov10635_mode_WXGA_1280_800, 1280, 800,
		  ov10635_setting_30fps_WXGA_1280_800,
		  ARRAY_SIZE(ov10635_setting_30fps_WXGA_1280_800)
		},
		{ ov10635_mode_720P_1280_720, 1280, 720,
		  ov10635_setting_30fps_720P_1280_720,
		  ARRAY_SIZE(ov10635_setting_30fps_720P_1280_720)
		},
		{ ov10635_mode_WVGA_752_480, 752, 480,
		  ov10635_setting_30fps_WVGA_752_480,
		  ARRAY_SIZE(ov10635_setting_30fps_WVGA_752_480)
		},
		{ ov10635_mode_VGA_640_480, 640, 480,
		  ov10635_setting_30fps_VGA_640_480,
		  ARRAY_SIZE(ov10635_setting_30fps_VGA_640_480)
		},
		{ ov10635_mode_CIF_352_288, 352, 288,
		  ov10635_setting_30fps_CIF_352_288,
		  ARRAY_SIZE(ov10635_setting_30fps_CIF_352_288)
		},
		{ ov10635_mode_QVGA_320_240, 320, 240,
		  ov10635_setting_30fps_QVGA_320_240,
		  ARRAY_SIZE(ov10635_setting_30fps_QVGA_320_240)
		},
	}
};

static inline struct sensor_data *subdev_to_sensor_data(struct v4l2_subdev *sd)
{
	return container_of(sd, struct sensor_data, subdev);
}

static enum ov10635_frame_rate to_ov10635_frame_rate(struct v4l2_fract *timeperframe)
{
	enum ov10635_frame_rate rate;
	u32 tgt_fps;	/* target frames per secound */

	tgt_fps = timeperframe->denominator / timeperframe->numerator;

	if (tgt_fps == 30)
		rate = OV10635_30_FPS;
	else if (tgt_fps == 15)
		rate = OV10635_15_FPS;
	else
		rate = -EINVAL;

	return rate;
}

static inline int ov10635_read_reg(struct sensor_data *max9286_data, int index,
				   unsigned short reg, unsigned char *val)
{
	struct i2c_client *client = max9286_data->i2c_client;
	struct device *dev = &client->dev;
	unsigned char u8_buf[2] = { 0 };
	unsigned int buf_len = 2;
	int retry, timeout = 10;
	unsigned char u8_val = 0;

	u8_buf[0] = (reg >> 8) & 0xFF;
	u8_buf[1] = reg & 0xFF;

	client->addr = ADDR_OV_SENSOR + index;

	for (retry = 0; retry < timeout; retry++) {
		if (i2c_master_send(client, u8_buf, buf_len) < 0) {
			dev_dbg(dev, "%s:read reg error on send: reg=0x%x, retry = %d.\n", __func__, reg, retry);
			msleep(5);
			continue;
		}
		if (i2c_master_recv(client, &u8_val, 1) != 1) {
			dev_dbg(dev, "%s:read reg error on recv: reg=0x%x, retry = %d.\n", __func__, reg, retry);
			msleep(5);
			continue;
		}
		break;
	}

	if (retry >= timeout) {
		dev_info(dev, "%s:read reg error: reg=0x%x.\n", __func__, reg);
		return -1;
	}

	*val = u8_val;

	return u8_val;
}

static inline int ov10635_write_reg(struct sensor_data *max9286_data, int index,
				    unsigned short reg, unsigned char val)
{
	struct i2c_client *client = max9286_data->i2c_client;
	struct device *dev = &client->dev;
	unsigned char u8_buf[3] = { 0 };
	unsigned int buf_len = 3;
	int retry, timeout = 10;

	u8_buf[0] = (reg >> 8) & 0xFF;
	u8_buf[1] = reg & 0xFF;
	u8_buf[2] = val;

	client->addr = ADDR_OV_SENSOR + index;
	for (retry = 0; retry < timeout; retry++) {
		if (i2c_master_send(client, u8_buf, buf_len) < 0) {
			dev_dbg(dev, "%s:write reg error: reg=0x%x, val=0x%x, retry = %d.\n", __func__, reg, val, retry);
			msleep(5);
			continue;
		}
		break;
	}

	if (retry >= timeout) {
		dev_info(dev, "%s:write reg error: reg=0x%x, val=0x%x.\n",
			 __func__, reg, val);
		return -1;
	}

	return 0;
}

static int ov10635_check_device(struct sensor_data *max9286_data, int index)
{
	struct i2c_client *client = max9286_data->i2c_client;
	struct device *dev = &client->dev;
	unsigned char reg = 0;

	ov10635_read_reg(max9286_data, index, OV10635_REG_PID, &reg);
	if (reg != 0xA6) {
		dev_err(dev, "%s: OV10635 hasn't been found, reg[0x%x] = 0x%x., index=%d\n",
			__func__, OV10635_REG_PID, reg, index);
		return -1;
	}
	ov10635_read_reg(max9286_data, index, OV10635_REG_VER, &reg);
	if (reg != 0x35) {
		dev_err(dev, "%s: OV10635 hasn't been found, reg[0x%x] = 0x%x.\n",
			__func__, OV10635_REG_VER, reg);
		return -1;
	}
	dev_info(dev, "%s: OV10635 index=%d was found.\n", __func__, index);

	return 0;
}

static int ov10635_download_firmware(struct sensor_data *max9286_data, int index,
				     struct reg_value *reg_setting, s32 arysize)
{
	register u32 delay_ms = 0;
	register u16 reg_addr = 0;
	register u8 val = 0;
	int i, retval = 0;

	for (i = 0; i < arysize; ++i, ++reg_setting) {
		delay_ms = reg_setting->delay_ms;
		reg_addr = reg_setting->reg_addr;
		val = reg_setting->val;

		retval = ov10635_write_reg(max9286_data, index, reg_addr, val);
		if (retval < 0)
			goto err;

		if (delay_ms)
			msleep(delay_ms);
	}
err:
	return retval;
}

static int ov10635_initialize(struct sensor_data *max9286_data, int index)
{
	struct device *dev = &max9286_data->i2c_client->dev; int i, array_size;
	int retval;

	dev_info(dev, "%s: index = %d.\n", __func__, index);
	array_size = ARRAY_SIZE(ov10635_init_data);
	for (i = 0; i < array_size; i++) {
		retval = ov10635_write_reg(max9286_data, index,
					   ov10635_init_data[i].reg_addr,
					   ov10635_init_data[i].val);
		if (retval < 0)
			break;
		if (ov10635_init_data[i].delay_ms != 0)
			msleep(ov10635_init_data[i].delay_ms);
	}

	return 0;
}

static inline int max9271_read_reg(struct sensor_data *max9286_data, int index, u8 reg)
{
	struct device *dev = &max9286_data->i2c_client->dev;
	int val;
	int retry, timeout = 10;

	max9286_data->i2c_client->addr = ADDR_MAX9271 + index;
	for (retry = 0; retry < timeout; retry++) {
		val = i2c_smbus_read_byte_data(max9286_data->i2c_client, reg);
		if (val < 0)
			msleep(5);
		else
			break;
	}

	if (retry >= timeout) {
		dev_info(dev, "%s:read reg error: reg=%2x\n", __func__, reg);
		return -1;
	}

	return val;
}

static int max9271_write_reg(struct sensor_data *max9286_data, int index, u8 reg, u8 val)
{
	struct i2c_client *client = max9286_data->i2c_client;
	struct device *dev = &client->dev;
	s32 ret;
	int retry, timeout = 10;

	max9286_data->i2c_client->addr = ADDR_MAX9271 + index;
	for (retry = 0; retry < timeout; retry++) {
		ret = i2c_smbus_write_byte_data(client, reg, val);
		if (ret < 0)
			msleep(5);
		else
			break;
	}
	dev_dbg(dev, "%s: addr %02x reg %02x val %02x\n", __func__, client->addr, reg, val);

	if (retry >= timeout) {
		dev_info(dev, "%s:write reg error:reg=%2x,val=%2x\n", __func__, reg, val);
		return -1;
	}

	return 0;
}

/*  Read one register from a MAX9286 i2c slave device.
 *
 *  @param *reg: register in the device we wish to access.
 *
 *  @return 0 if success, an error code otherwise.
 */
static inline int max9286_read_reg(struct sensor_data *max9286_data, u8 reg)
{
	int val;

	max9286_data->i2c_client->addr = ADDR_MAX9286;
	val = i2c_smbus_read_byte_data(max9286_data->i2c_client, reg);
	if (val < 0) {
		dev_info(&max9286_data->i2c_client->dev,
			 "%s:read reg error: reg=%2x\n", __func__, reg);
		return -1;
	}
	return val;
}

/*  Write one register of a MAX9286 i2c slave device.
 *
 *  @param *reg: register in the device we wish to access.
 *
 *  @return 0 if success, an error code otherwise.
 */
static int max9286_write_reg(struct sensor_data *max9286_data, u8 reg, u8 val)
{
	struct i2c_client *client = max9286_data->i2c_client;
	struct device *dev = &client->dev;
	s32 ret;

	client->addr = ADDR_MAX9286;
	ret = i2c_smbus_write_byte_data(client, reg, val);

	dev_dbg(dev, "addr %02x reg %02x val %02x\n", client->addr, reg, val);

	if (ret < 0) {
		dev_info(dev, "write reg error:reg=%2x,val=%2x\n", reg, val);
		return -1;
	}
	return 0;
}

#ifdef debug
static void max9271_dump_registers(struct sensor_data *max9286_data, int index)
{
	unsigned char i;

	pr_info("max9271_dump_registers: index = %d.\r\n", index);
	for (i = 0; i < 0x20; i++)
		pr_info("MAX9271 Reg 0x%02x = 0x%x.\r\n",
			i, max9271_read_reg(max9286_data, index, i));
}

static void max9286_dump_registers(struct sensor_data *max9286_data)
{
	unsigned char i;

	pr_info("Dump MAX9286 registers:\r\n");
	for (i = 0; i < 0x72; i++)
		pr_info("MAX9286 Reg 0x%02x = 0x%x.\r\n",
			i, max9286_read_reg(max9286_data, i));
}
#else
static void max9271_dump_registers(struct sensor_data *max9286_data, int index)
{
}
#endif

static void max9286_hw_reset(struct sensor_data *max9286_data)
{
	gpiod_set_value_cansleep(max9286_data->pwn_gpio, 0);
	udelay(200);
	gpiod_set_value_cansleep(max9286_data->pwn_gpio, 1);
	msleep(1);
}

static int max9286_hardware_preinit(struct sensor_data *max9286_data)
{
	u8 reg;

	dev_info(&max9286_data->i2c_client->dev, "In %s()\n", __func__);

	/* Disable CSI Output */
	max9286_write_reg(max9286_data, 0x15, 0x03);

	/* Enable PRBS test */
	max9286_write_reg(max9286_data, 0x0E, 0x5F);
	msleep(10);

	/* Enable Custom Reverse Channel & First Pulse Length  STEP 1 */
	max9286_write_reg(max9286_data, 0x3F, 0x4F);
	msleep(2); /* STEP 2 */

	/* Reverse Channel Amplitude to mid level and transition time */
	max9286_write_reg(max9286_data, 0x3B, 0x1E); /* STEP 3 */
	msleep(2); /* STEP 4 */

	/* Enable MAX9271 Configuration Link */
	max9271_write_reg(max9286_data, 0, 0x04, 0x43);  /* STEP 5 */
	msleep(2);  /* STEP 6 */

	/* Increase serializer reverse channel input thresholds */
	max9271_write_reg(max9286_data, 0, 0x08, 0x01);  /* STEP 7 */
	msleep(2);  /* STEP 8 */

	/* Reverse Channel Amplitude level */
	max9286_write_reg(max9286_data, 0x3B, 0x19);  /* STEP 9 */
	msleep(5);  /* STEP 10 */

	/* Set YUV422 8 bits mode, Double Data Rate, 4 data lane */
	max9286_write_reg(max9286_data, 0x12, 0xF3); /* STEP 12 */

	max9286_write_reg(max9286_data, 0x01, 0x02); /* STEP 13 */
	/* Enable All Link 0-3  */
	max9286_write_reg(max9286_data, 0x00, 0xef); /* STEP 14 */

	/* Frame Sync */
	/* Automatic Mode */
	max9286_write_reg(max9286_data, 0x01, 0x02);/* STEP 13 */
	msleep(200);
	/* Detect link */
	max9286_data->sensor_num = 0;
	reg = max9286_read_reg(max9286_data, 0x49);
	max9286_data->sensor_is_there = ((reg >> 4) & 0xF) | (reg & 0xF);
	if (max9286_data->sensor_is_there & (0x1 << 0))
		max9286_data->sensor_num += 1;
	if (max9286_data->sensor_is_there & (0x1 << 1))
		max9286_data->sensor_num += 1;
	if (max9286_data->sensor_is_there & (0x1 << 2))
		max9286_data->sensor_num += 1;
	if (max9286_data->sensor_is_there & (0x1 << 3))
		max9286_data->sensor_num += 1;
	pr_info("max9286_mipi: reg = 0x%02x.\n", reg);
	pr_info("max9286_mipi: sensor number = %d.\n", max9286_data->sensor_num);

	if (max9286_data->sensor_num == 0) {
		pr_err("%s: no camera connected.\n", __func__);
		return -1;
	}

	return 0;
}

static void max9286_camera_reorder(struct sensor_data *max9286_data)
{
	u8 reg;

	reg = 0xE4;
	if (max9286_data->sensor_num == 1) {
		switch (max9286_data->sensor_is_there) {
		case 0x8:
			reg = 0x27;
			break;
		case 0x4:
			reg = 0xC6;
			break;
		case 0x2:
			reg = 0xE1;
			break;
		case 0x1:
		default:
			reg = 0xE4;
			break;
		}
	} else if (max9286_data->sensor_num == 2) {
		switch (max9286_data->sensor_is_there) {
		case 0xC:
			reg = 0x4E;
			break;
		case 0xA:
			reg = 0x72;
			break;
		case 0x9:
			reg = 0x78;
			break;
		case 0x6:
			reg = 0xD2;
			break;
		case 0x5:
			reg = 0xD8;
			break;
		case 0x3:
		default:
			reg = 0xE4;
			break;
		}
	} else if (max9286_data->sensor_num == 3) {
		switch (max9286_data->sensor_is_there) {
		case 0xE:
			reg = 0x93;
			break;
		case 0xD:
			reg = 0x9C;
			break;
		case 0xB:
			reg = 0xB4;
			break;
		case 0x7:
		default:
			reg = 0xE4;
			break;
		}
	}
	max9286_write_reg(max9286_data, 0x0B, reg);
}

static int max9286_hardware_init(struct sensor_data *max9286_data)
{
	int retval = 0;
	int i;
	u8 reg, sensor_addr = 0;

	dev_info(&max9286_data->i2c_client->dev, "In %s()\n", __func__);

	/* Disable PRBS test */
	max9286_write_reg(max9286_data, 0x0E, 0x50);

	/* reorder camera */
	max9286_camera_reorder(max9286_data);

	/* Enable all links */
	reg = 0xE0 | max9286_data->sensor_is_there;
	max9286_write_reg(max9286_data, 0x00, reg);

	/* Set up links */
	sensor_addr = ADDR_OV_SENSOR;
	max9271_write_reg(max9286_data, 0, 0x07, 0x84);
	/* STEP 15-46 */
	reg = 0;
	for (i = 1; i <= MAX9271_MAX_SENSOR_NUM; i++) {
		if (((0x1 << (i - 1)) & max9286_data->sensor_is_there) == 0)
			continue;

		/* Enable Link control channel */
		reg |= (0x11 << (i - 1));
		max9286_write_reg(max9286_data, 0x0A, reg);/* STEP 15 */

		/* Set MAX9271 new address for link 0 */
		max9271_write_reg(max9286_data, 0, 0x00, (ADDR_MAX9271 + i) << 1);
		msleep(2);

		max9271_write_reg(max9286_data, i, 0x01, ADDR_MAX9286 << 1);
		max9271_write_reg(max9286_data, i, 0x09, (sensor_addr + i) << 1);
		max9271_write_reg(max9286_data, i, 0x0A, sensor_addr << 1);
		max9271_write_reg(max9286_data, i, 0x0B, ADDR_MAX9271_ALL << 1);
		max9271_write_reg(max9286_data, i, 0x0C, (ADDR_MAX9271 + i) << 1);

		msleep(1);
		pr_info("max9286_mipi: initialized sensor  = 0x%02x.\n", i);
		max9271_dump_registers(max9286_data, i);
	}
	max9286_write_reg(max9286_data, 0x0A, reg);
	max9286_write_reg(max9286_data, 0x0A, reg);

	/* Disable Local Auto I2C ACK */
	max9286_write_reg(max9286_data, 0x34, 0x36); /* STEP 48 */

	/* Initialize Camera Sensor */
	/* STEP 49 */
	if (max9286_data->sensor_is_there & (0x1 << 0)) {
		retval = ov10635_check_device(max9286_data, 1);
		if (retval < 0)
			return retval;
		ov10635_initialize(max9286_data, 0);
	}

	if (max9286_data->sensor_is_there & (0x1 << 1)) {
		retval = ov10635_check_device(max9286_data, 2);
		if (retval < 0)
			return retval;
		ov10635_initialize(max9286_data, 1);
	}

	if (max9286_data->sensor_is_there & (0x1 << 2)) {
		retval = ov10635_check_device(max9286_data, 3);
		if (retval < 0)
			return retval;
		ov10635_initialize(max9286_data, 2);
	}

	if (max9286_data->sensor_is_there & (0x1 << 3)) {
		retval = ov10635_check_device(max9286_data, 4);
		if (retval < 0)
			return retval;
		ov10635_initialize(max9286_data, 3);
	}

	/* Enable Local Auto I2C ACK */
	max9286_write_reg(max9286_data, 0x34, 0xB6); /* STEP 50 */

	/* MAX9271: Enable Serial Links and Disable Configuration Link */
	max9271_write_reg(max9286_data, ADDR_MAX9271_ALL - ADDR_MAX9271, 0x04, 0x83); /* STEP 51 */
	/* Wait for more than 2 frame time */
	msleep(1000); /* STEP 52 */

	/* Enable CSI output, set virtual channel according to the link number */
	max9286_write_reg(max9286_data, 0x15, 0x9B); /* STEP 52 */
	msleep(10);
	return retval;
}

static int ov10635_change_mode(struct sensor_data *max9286_data)
{
	struct reg_value *reg_setting = NULL;
	enum ov10635_mode mode = max9286_data->current_mode;
	enum ov10635_frame_rate rate =
				to_ov10635_frame_rate(&max9286_data->frame_interval);
	int arysize = 0, retval = 0;

	if (mode > ov10635_mode_MAX || mode < ov10635_mode_MIN) {
		pr_err("Wrong ov10635 mode detected!\n");
		return -1;
	}

	reg_setting = ov10635_mode_info_data[rate][mode].init_data_ptr;
	arysize = ov10635_mode_info_data[rate][mode].init_data_size;

	max9286_data->format.width = ov10635_mode_info_data[rate][mode].width;
	max9286_data->format.height = ov10635_mode_info_data[rate][mode].height;

	if (max9286_data->format.width == 0 ||
	    max9286_data->format.height == 0 ||
	    !reg_setting || arysize == 0) {
		pr_err("Not support mode=%d %s\n", mode,
		       (rate == 0) ? "15(fps)" : "30(fps)");
		return -EINVAL;
	}

	retval = ov10635_download_firmware(max9286_data, 0, reg_setting, arysize);

	return retval;
}

static int max9286_enum_mbus_code(struct v4l2_subdev *sd,
				  struct v4l2_subdev_state *sd_state,
				  struct v4l2_subdev_mbus_code_enum *code)
{
	struct sensor_data *max9286_data = subdev_to_sensor_data(sd);

	code->code = max9286_data->format.code;
	return 0;
}

/*
 * max9286_enum_framesizes - V4L2 sensor interface handler for
 *			     VIDIOC_ENUM_FRAMESIZES ioctl
 * @s: pointer to standard V4L2 device structure
 * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
 *
 * Return 0 if successful, otherwise -EINVAL.
 */
static int max9286_enum_framesizes(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *sd_state,
				   struct v4l2_subdev_frame_size_enum *fse)
{
	if (fse->index > ov10635_mode_MAX)
		return -EINVAL;

	fse->max_width = max(ov10635_mode_info_data[0][fse->index].width,
			     ov10635_mode_info_data[1][fse->index].width);
	fse->min_width = fse->max_width;

	fse->max_height = max(ov10635_mode_info_data[0][fse->index].height,
			      ov10635_mode_info_data[1][fse->index].height);
	fse->min_height = fse->max_height;

	return 0;
}

static int max9286_enum_frame_interval(struct v4l2_subdev *sd,
				       struct v4l2_subdev_state *sd_state,
				       struct v4l2_subdev_frame_interval_enum *fie)
{
	int i, j, count;

	if (fie->index > ov10635_mode_MAX)
		return -EINVAL;

	if (fie->width == 0 || fie->height == 0 || fie->code == 0) {
		pr_warn("Please assign pixel format, width and height.\n");
		return -EINVAL;
	}

	fie->interval.numerator = 1;

	 /* TODO Reserved to extension */
	count = 0;
	for (i = 0; i < ARRAY_SIZE(ov10635_framerates); i++) {
		for (j = 0; j < (ov10635_mode_MAX + 1); j++) {
			if (fie->width == ov10635_mode_info_data[i][j].width &&
			    fie->height == ov10635_mode_info_data[i][j].height &&
			    ov10635_mode_info_data[i][j].init_data_ptr)
				count++;

			if (fie->index == (count - 1)) {
				fie->interval.denominator = ov10635_framerates[i];
				return 0;
			}
		}
	}

	return -EINVAL;
}

static int max9286_get_fmt(struct v4l2_subdev *sd,
			   struct v4l2_subdev_state *sd_state,
			   struct v4l2_subdev_format *fmt)
{
	struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
	struct v4l2_mbus_framefmt *mf = &fmt->format;

	if (fmt->pad)
		return -EINVAL;

	mf->code        = max9286_data->format.code;
	mf->width       = max9286_data->format.width;
	mf->height      = max9286_data->format.height;
	mf->colorspace  = max9286_data->format.colorspace;
	mf->field       = max9286_data->format.field;
	mf->reserved[0] = max9286_data->format.reserved[0];

	return 0;
}

static struct ov10635_mode_info *get_max_resolution(enum ov10635_frame_rate rate)
{
	u32 max_width;
	enum ov10635_mode mode;
	int i;

	mode = 0;
	max_width  = ov10635_mode_info_data[rate][0].width;

	for (i = 0; i < (ov10635_mode_MAX + 1); i++) {
		if (ov10635_mode_info_data[rate][i].width > max_width) {
			max_width = ov10635_mode_info_data[rate][i].width;
			mode = i;
		}
	}
	return &ov10635_mode_info_data[rate][mode];
}

static struct ov10635_mode_info *match(struct v4l2_mbus_framefmt *fmt,
				       enum ov10635_frame_rate rate)
{
	struct ov10635_mode_info *info;
	int i;

	for (i = 0; i < (ov10635_mode_MAX + 1); i++) {
		if (fmt->width == ov10635_mode_info_data[rate][i].width &&
		    fmt->height == ov10635_mode_info_data[rate][i].height) {
			info = &ov10635_mode_info_data[rate][i];
			break;
		}
	}
	if (i == ov10635_mode_MAX + 1)
		info = NULL;

	return info;
}

static bool try_to_find_resolution(struct sensor_data *sensor,
				   const enum ov10635_frame_rate fr,
				   struct v4l2_mbus_framefmt *mf)
{
	enum ov10635_mode mode = sensor->current_mode;
	enum ov10635_frame_rate frame_rate = fr;
	struct device *dev = &sensor->i2c_client->dev;
	struct ov10635_mode_info *info;
	bool found = false;

	if ((mf->width == ov10635_mode_info_data[frame_rate][mode].width) &&
	    (mf->height == ov10635_mode_info_data[frame_rate][mode].height)) {
			info = &ov10635_mode_info_data[frame_rate][mode];
			found = true;
	} else {
		/* get mode info according to frame user's width and height */
		info = match(mf, frame_rate);
		if (!info) {
			frame_rate ^= 0x1;
			info = match(mf, frame_rate);
			if (info) {
				sensor->current_mode = -1;
				dev_err(dev, "%s %dx%d only support %s(fps)\n",
					__func__,
					info->width, info->height,
					(frame_rate == 0) ? "15fps" : "30fps");
				return false;
			}
			goto max_resolution;
		}
		found = true;
	}

	/* get max resolution to resize */
max_resolution:
	if (!found) {
		frame_rate ^= 0x1;
		info = get_max_resolution(frame_rate);
	}

	sensor->current_mode = info->mode;
	sensor->frame_interval.denominator = (frame_rate) ? 30 : 15;
	sensor->format.width  = info->width;
	sensor->format.height = info->height;

	return found;
}

static int max9286_set_fmt(struct v4l2_subdev *sd,
			   struct v4l2_subdev_state *sd_state,
			   struct v4l2_subdev_format *fmt)
{
	struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
	struct v4l2_mbus_framefmt *mf = &fmt->format;
	enum ov10635_frame_rate frame_rate = max9286_data->current_fr;
	int ret;

	if (fmt->pad)
		return -EINVAL;

	mf->code       = max9286_data->format.code;
	mf->colorspace = max9286_data->format.colorspace;
	mf->field      = V4L2_FIELD_NONE;

	try_to_find_resolution(max9286_data, frame_rate, mf);

	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
		return 0;

	ret = ov10635_change_mode(max9286_data);

	return ret;
}

static int max9286_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
				  struct v4l2_mbus_frame_desc *fd)
{
	return 0;
}

static int max9286_set_frame_desc(struct v4l2_subdev *sd,
				  unsigned int pad,
				  struct v4l2_mbus_frame_desc *fd)
{
	return 0;
}

static int max9286_set_power(struct v4l2_subdev *sd, int on)
{
	return 0;
}

static int ov10635_try_frame_interval(struct sensor_data *sensor,
				      struct v4l2_fract *fi,
				      u32 width, u32 height)
{
	enum ov10635_frame_rate rate = OV10635_15_FPS;
	int minfps, maxfps, best_fps, fps;
	int i;

	minfps = ov10635_framerates[OV10635_15_FPS];
	maxfps = ov10635_framerates[OV10635_30_FPS];

	if (fi->numerator == 0) {
		fi->denominator = ov10635_framerates[OV10635_30_FPS];
		fi->numerator = 1;
		rate = OV10635_30_FPS;
		goto out;
	}

	fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
			minfps, maxfps);

	best_fps = minfps;
	for (i = 0; i < ARRAY_SIZE(ov10635_framerates); i++) {
		int curr_fps = ov10635_framerates[i];

		if (abs(curr_fps - fps) < abs(best_fps - fps)) {
			best_fps = curr_fps;
			rate = i;
		}
	}

	fi->numerator = 1;
	fi->denominator = best_fps;

out:
	return rate;
}

static int max9286_g_frame_interval(struct v4l2_subdev *sd,
				    struct v4l2_subdev_frame_interval *fi)
{
	struct sensor_data *max9286_data = subdev_to_sensor_data(sd);

	mutex_lock(&max9286_data->lock);
	fi->interval = max9286_data->frame_interval;
	mutex_unlock(&max9286_data->lock);

	return 0;
}

static int max9286_s_frame_interval(struct v4l2_subdev *sd,
				    struct v4l2_subdev_frame_interval *fi)
{
	struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
	enum ov10635_mode mode = max9286_data->current_mode;
	enum ov10635_frame_rate fr = max9286_data->current_fr;
	struct v4l2_mbus_framefmt mf;
	bool found = false;
	int frame_rate, ret = 0;

	if (fi->pad != 0)
		return -EINVAL;

	mutex_lock(&max9286_data->lock);

	memset(&mf, 0, sizeof(mf));
	mf.width  = ov10635_mode_info_data[fr][mode].width;
	mf.height = ov10635_mode_info_data[fr][mode].height;
	frame_rate = ov10635_try_frame_interval(max9286_data, &fi->interval,
						mf.width, mf.height);
	if (frame_rate < 0) {
		fi->interval = max9286_data->frame_interval;
		goto out;
	}

	mf.width  = ov10635_mode_info_data[frame_rate][mode].width;
	mf.height = ov10635_mode_info_data[frame_rate][mode].height;
	found = try_to_find_resolution(max9286_data, frame_rate, &mf);
	if (!found) {
		ret = -EINVAL;
		goto out;
	}

	max9286_data->current_fr = frame_rate;
	max9286_data->frame_interval = fi->interval;

out:
	mutex_unlock(&max9286_data->lock);
	return ret;
}

static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct sensor_data *max9286_data = subdev_to_sensor_data(sd);

	dev_dbg(sd->dev, "%s\n", __func__);
	if (enable) {
		if (!max9286_data->running++) {
			/*
			 * Enable CSI output, set virtual channel
			 * according to the link number
			 */
			max9286_write_reg(max9286_data, 0x15, 0x9B);
		}

	} else {

		if (!--max9286_data->running) {
			/* Disable CSI Output */
			max9286_write_reg(max9286_data, 0x15, 0x03);
		}
	}

	return 0;
}

static int max9286_link_setup(struct media_entity *entity,
			      const struct media_pad *local,
			      const struct media_pad *remote,
			      u32 flags)
{
	return 0;
}

static const struct v4l2_subdev_pad_ops max9286_pad_ops = {
	.enum_mbus_code		= max9286_enum_mbus_code,
	.enum_frame_size	= max9286_enum_framesizes,
	.enum_frame_interval	= max9286_enum_frame_interval,
	.get_fmt		= max9286_get_fmt,
	.set_fmt		= max9286_set_fmt,
	.get_frame_desc		= max9286_get_frame_desc,
	.set_frame_desc		= max9286_set_frame_desc,
};

static const struct v4l2_subdev_core_ops max9286_core_ops = {
	.s_power	= max9286_set_power,
};

static const struct v4l2_subdev_video_ops max9286_video_ops = {
	.g_frame_interval = max9286_g_frame_interval,
	.s_frame_interval = max9286_s_frame_interval,
	.s_stream	  = max9286_s_stream,
};

static const struct v4l2_subdev_ops max9286_subdev_ops = {
	.core	= &max9286_core_ops,
	.pad	= &max9286_pad_ops,
	.video	= &max9286_video_ops,
};

static const struct media_entity_operations max9286_sd_media_ops = {
	.link_setup = max9286_link_setup,
};

ssize_t analog_test_pattern_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	struct v4l2_subdev *sd = dev_get_drvdata(dev);
	struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
	u8 val = 0;

	ov10635_read_reg(max9286_data, 0, 0x370A, &val);
	return sprintf(buf, "%s\n", (val & 0x4) ? "enabled" : "disabled");
}

static ssize_t analog_test_pattern_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf, size_t count)
{
	struct v4l2_subdev *sd = dev_get_drvdata(dev);
	struct sensor_data *max9286_data = subdev_to_sensor_data(sd);
	char enabled[32];

	if (sscanf(buf, "%s", enabled) > 0) {
		if (strcmp(enabled, "enable") == 0)
			ov10635_write_reg(max9286_data, 0, 0x370A, 0x4);
		else
			ov10635_write_reg(max9286_data, 0, 0x370A, 0x0);
		return count;
	}
	return -EINVAL;
}

static DEVICE_ATTR_RW(analog_test_pattern);

/*!
 * max9286 I2C probe function
 *
 * @param adapter            struct i2c_adapter *
 * @return  Error code indicating success or failure
 */
static int max9286_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct sensor_data *max9286_data;
	struct v4l2_subdev *sd;
	int retval;

	max9286_data = devm_kzalloc(dev, sizeof(*max9286_data), GFP_KERNEL);
	if (!max9286_data)
		return -ENOMEM;

	/* Set initial values for the sensor struct. */
	max9286_data->sensor_clk = devm_clk_get(dev, "capture_mclk");
	if (IS_ERR(max9286_data->sensor_clk)) {
		/* assuming clock enabled by default */
		dev_err(dev, "clock-frequency missing or invalid\n");
		return PTR_ERR(max9286_data->sensor_clk);
	}

	retval = of_property_read_u32(dev->of_node, "mclk", &max9286_data->mclk);
	if (retval) {
		dev_err(dev, "mclk missing or invalid\n");
		return retval;
	}

	retval = of_property_read_u32(dev->of_node, "mclk_source", (u32 *)&max9286_data->mclk_source);
	if (retval) {
		dev_err(dev, "mclk_source missing or invalid\n");
		return retval;
	}

	/* request power down pin */
	max9286_data->pwn_gpio = devm_gpiod_get_optional(dev, "pwn-gpios",
							GPIOD_OUT_HIGH);
	if (IS_ERR(max9286_data->pwn_gpio))
		return PTR_ERR(max9286_data->pwn_gpio);

	max9286_hw_reset(max9286_data);

	clk_prepare_enable(max9286_data->sensor_clk);

	mutex_init(&max9286_data->lock);

	max9286_data->i2c_client        = client;
	max9286_data->format.code       = MEDIA_BUS_FMT_YUYV8_1X16;
	max9286_data->format.width      = ov10635_mode_info_data[1][0].width;
	max9286_data->format.height     = ov10635_mode_info_data[1][0].height;
	max9286_data->format.colorspace = V4L2_COLORSPACE_JPEG;

	/*
	 * Pass mipi phy clock rate Mbps
	 * fcsi2 = PCLk * WIDTH * CHANNELS / LANES
	 * fsci2 = 72MPCLK * 8 bit * 4 channels / 4 lanes
	 */
	max9286_data->format.reserved[0] = 72 * 8;
	max9286_data->format.field = V4L2_FIELD_NONE;
	max9286_data->current_mode = 0;
	max9286_data->frame_interval.denominator = 30;
	max9286_data->frame_interval.numerator = 1;
	max9286_data->is_mipi = 1;

	retval = max9286_read_reg(max9286_data, 0x1e);
	if (retval != 0x40) {
		pr_warn("max9286 is not found, chip id reg 0x1e = 0x(%x)\n", retval);
		clk_disable_unprepare(max9286_data->sensor_clk);
		return -ENODEV;
	}

	max9286_hardware_preinit(max9286_data);

	if  (max9286_data->sensor_num == 0) {
		pr_warn("cameras are not found,\n");
		clk_disable_unprepare(max9286_data->sensor_clk);
		return -ENODEV;
	}

	max9286_data->frame_interval.denominator = 30;
	max9286_data->frame_interval.numerator   = 1;
	max9286_data->v_channel = 0;
	max9286_data->cap_mode.clip_top  = 0;
	max9286_data->cap_mode.clip_left = 0;

	max9286_data->cap_mode.clip_height = 800;
	max9286_data->cap_mode.clip_width  = 1280;

	max9286_data->cap_mode.hlen = max9286_data->cap_mode.clip_width;

	max9286_data->cap_mode.hfp   = 0;
	max9286_data->cap_mode.hbp   = 0;
	max9286_data->cap_mode.hsync = 625;
	max9286_data->cap_mode.vlen  = 800;
	max9286_data->cap_mode.vfp   = 0;
	max9286_data->cap_mode.vbp   = 0;
	max9286_data->cap_mode.vsync = 40;
	max9286_data->cap_mode.vlen1 = 0;
	max9286_data->cap_mode.vfp1  = 0;
	max9286_data->cap_mode.vbp1  = 0;
	max9286_data->cap_mode.vsync1 = 0;
	max9286_data->cap_mode.pixelclock = 27000000;

	sd = &max9286_data->subdev;
	v4l2_i2c_subdev_init(sd, client, &max9286_subdev_ops);
	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
	max9286_data->pads[MIPI_CSI2_SENS_VC0_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
	max9286_data->pads[MIPI_CSI2_SENS_VC1_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
	max9286_data->pads[MIPI_CSI2_SENS_VC2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
	max9286_data->pads[MIPI_CSI2_SENS_VC3_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
	retval = media_entity_pads_init(&sd->entity, MIPI_CSI2_SENS_VCX_PADS_NUM,
					max9286_data->pads);
	if (retval < 0)
		return retval;

	max9286_data->subdev.entity.ops = &max9286_sd_media_ops;
	retval = v4l2_async_register_subdev(&max9286_data->subdev);
	if (retval < 0) {
		dev_err(dev, "Async register failed, ret=(%d)\n", retval);
		media_entity_cleanup(&sd->entity);
	}

	retval = max9286_hardware_init(max9286_data);
	if (retval < 0) {
		dev_err(dev, "camera init failed\n");
		clk_disable_unprepare(max9286_data->sensor_clk);
		media_entity_cleanup(&sd->entity);
		v4l2_async_unregister_subdev(sd);
		return retval;
	}

	max9286_data->running = 0;

	/* Disable CSI Output */
	max9286_write_reg(max9286_data, 0x15, 0x03);

	/*Create device attr in sys */
	retval = device_create_file(&client->dev, &dev_attr_analog_test_pattern);
	if (retval < 0) {
		dev_err(dev, "%s: create device file fail\n", __func__);
		return retval;
	}

	dev_info(dev, "max9286_mipi is found, name %s\n", sd->name);
	return retval;
}

/*!
 * max9286 I2C detach function
 *
 * @param client            struct i2c_client *
 * @return  Error code indicating success or failure
 */
static void max9286_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd = i2c_get_clientdata(client);
	struct sensor_data *max9286_data = subdev_to_sensor_data(sd);

	clk_disable_unprepare(max9286_data->sensor_clk);
	device_remove_file(&client->dev, &dev_attr_analog_test_pattern);
	media_entity_cleanup(&sd->entity);
	v4l2_async_unregister_subdev(sd);
}

static const struct i2c_device_id max9286_id[] = {
	{},
};
MODULE_DEVICE_TABLE(i2c, max9286_id);

static const struct of_device_id max9286_of_match[] = {
	{ .compatible = "maxim,max9286_mipi" },
	{ /* sentinel */ }
};

static struct i2c_driver max9286_i2c_driver = {
	.driver = {
		.owner = THIS_MODULE,
		.name   = "max9286_mipi",
		.of_match_table	= of_match_ptr(max9286_of_match),
	},
	.probe  = max9286_probe,
	.remove = max9286_remove,
	.id_table = max9286_id,
};

module_i2c_driver(max9286_i2c_driver);

MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("MAX9286 GSML Deserializer Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
MODULE_ALIAS("CSI");
